一、问题
- 使用
html-docx-js-typescript
将富文本导出为word文档时,通过style
设置的<img>
图片宽高不会生效,图片仍显示为原图大小。 - 查询后得知,只能通过
<img>
的原生属性width
和height
来设置图片的宽高。 - 经试验,当单独设置图片
width
和height
其中一个属性时,另一个属性不会按比例缩放,而是仍保持原大小。
二、背景
最近有个需求,将项目中原来的
将富文本导出为pdf
的功能改为将富文本导出为word
,本以为只是换一个插件导出即可的小事情,结果在实践的时候发现导出pdf与导出word竟还有些许不同之处,就比如本文的问题:在导出pdf
时,我们可以通过style来设置图片的大小,这与我们在富文本编辑器中所见的相同;然而到了导出word
的时候,就会发现这些样式完全不生效,导出的图片大大小小,有些甚至因为图片过大而超出了word编辑器的界限,为了使导出的word文档看起来令人舒适/方便查看,那么图片大小一定要相对统一(这边要求让所有图片的宽度保持一致)。
三、解决方法
- 根据以上问题描述,我们可以发现,此
问题的根源
就在于如何获取图片的宽高比例
,从而动态地设置图片的width
与height
属性。 - 可以通过使用HTML中的
Image对象
加载图片,然后读取其来获取图片的宽高属性:
function getImageSize(url) {
return new Promise(function(resolve, reject) {
const image = new Image()
image.src = url
image.onload = function() {
resolve({
width: image.width, // 图片原宽度
height: image.height, // 图片原高度
scale: image.height / image.width, // 图片高度与宽度之比
scaleWidth: 300, // 设置的缩放后的宽度为300,可根据实际需求调整
scaleHeight: (image.height / image.width) * 300, // 计算缩放后的高度
src: url // 图片url
})
}
image.onerror = function() {
reject(new Error('error'))
}
})
}
- 那么我们要在富文本模板中设置
src
为url
的图片img
的大小,则:
const size = await getImageSize(url)
const imgHtml = `<img src="${url}" width="${size.scaleWidth}" height="${size.scaleHeight}" />`
- 若是一个图片列表
imgList
,则:
const imgsPromise = imgList.map(async url => {
const size = await getImageSize(url)
return `<img src="${url}" width="${size.scaleWidth}" height="${size.scaleHeight}" />`
})
const imgs = await Promise.all(imgsPromise )
- 由于通过
getImageSize()
方法返回的是一个Promise
,因此,如果我们通过一个方法返回富文本内容时,需要:
// 原
export function getHtml() {
const imgHtml = <img src="xxxxxx"/>
return `
……// 内容
${imgHtml}
……// 内容
`
}
// 改后
export async function getHtml() {
const size = await getImageSize(url)
const imgHtml = `<img src="${url}" width="${size.scaleWidth}" height="${size.scaleHeight}" />`
return `
……// 内容
${imgHtml}
……// 内容
`
}
- 在使用时:
// 原
const html = getHtml()
// 改后
const html = await getHtml()