目录
一. docx.js生成图片API;
二. docx.js 通过图片url生成遇到的问题:
- 如何获取图片的原图大小
- 在获取原图大小的过程中出现异步问题
三. 最终代码
一. docx.js生成图片API
import * as fs from 'fs';
import { Document, ImageRun, Paragraph } from 'docx.js';
const doc = new Document([
sections: [
children: [
new Paragraph([
children: [
new ImageRun({
data: fs.readFileSync('./demo/images/image1.png'),
transformation: {
width: 100,
height: 100
}
})
]
])
]
]
])
二. docx.js 通过图片url生成遇到的问题:
- 如何获取图片的原图大小
解决方法: 通过生成img dom,来获取图片原始的大小;
- 在获取原图大小的过程中出现异步问题:
解决方法: 在循环图片的时候,出现了异步,解决方法用 async/await解决;
- 加载的顺序和之前的顺序一致问题:
解决方法: 用一个独一无二的占位符先先占children中的一个位置,加载成功后替换即可,在这里我使用的是src;当图片开始加载的时候, src占据图片原本应该占据的位置,等图片加载完成后,根据src的位置,替换加载成功后生成image的段落。
代码如下:
import { Document, ImageRun, Paragraph } from 'docx.js';
async createImage(src){
const blob = await fetch(src).then(res => res.blob())
return blob
}
async getImageFromUrl(src) {
return new Promise((resolve, reject) => {
let img = new Image()
img.onload = function() {
resolve(src)
}
img.onerror = function() {
reject('加载失败')
}
})
}
async getImageSize(src) {
const img = await getImageFromUrl(src).then(img => img).catch(err => console.log(err))
}
createParagraph(children) {
return new Paragraph({
children: [children]
})
}
let arrImage = ['http://demo/1.jpg', 'http://demo/2.jpg','http://demo/3.jpg', 'http://demo/4.jpg', 'http://demo/5.jpg']
children = []
await Promise.all(arrImage.map(async function (src) {
children.push(src)
let blob = await createImage(src)
let image = await getImageFromUrl(src)
let childIndex = children.indexOf(src)
if (childIndex > -1) {
children[childIndex] = createParagraph(new ImageRun({
data: blob,
transformation: {
width: image.width,
height: image.height
}
}))
}
}))
const doc = new Document([
sections: [
{
children: children
}
]
])
总结: 这里涉及到一个map和async/await的问题, 上面代码 arrImage.map(async function (src) {....}), 这里面实际上是是 [promise1, promise2, promise3...], 必须使用Promise.all()