yarn add jszip@3.10.1
yarn add jszip-utils@0.1.0
yarn add pizzip@3.1.4
yarn add docxtemplater@3.29.5
yarn add docxtemplater-image-module-free@1.1.1
yarn add file-saver@2.0.5
注意:这里的fileUrl必须是绝对路径,否则可能会报 is not zip的错误,请大家注意。
import ImageModule from 'docxtemplater-image-module-free'
import JSZipUtils from 'jszip-utils'
import Docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
export const exportDocx = (fileUrl, data) => {
return new Promise((resolve) => {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(fileUrl, (error, content) => {
// 创建一个PizZip实例,内容为模板的内容
if (error) {
throw error // 错误处理
}
const imageOpts = {
getImage: async function (tagValue, tagName) {
// 这里尝试了很多次,需要将图片链接转为ArrayBuffer,字节数组的形式。
const res = await URLToArrayBuffer(tagValue)
return res
},
getSize: function (img, tagValue, tagName) {
return [120, 180]
},
}
const imageModule = new ImageModule(imageOpts)
let zip = new PizZip(content)
// 创建并加载docxtemplater实例对象
let doc = new Docxtemplater()
doc.attachModule(imageModule)
doc.loadZip(zip)
doc.setOptions({ paragraphLoop: true, linebreaks: false })
doc.compile()
// 设置模板变量的值
doc.renderAsync({ ...data }).then(() => {
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
let out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
})
resolve({ out, data })
})
})
})
}
这里将url地址转ArrayBuffer的方法有很多。我看网上很多都是先将转为base64然后转为ArrayBuffer。我没有按这种方式,我是发送了一次请求,响应类型为arraybuffer。
function URLToArrayBuffer(url) {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.responseType = 'arraybuffer'
xhr.onload = function () {
if (xhr.status === 200) {
resolve(xhr.response)
}
}
xhr.send()
})
}
然后就是批量导出word文档
我这里写一个demo
这是一个点击事件。
const arr = new Array(10);
const data = {} // 渲染摸板需要的数据
const exportWord=()=>{
const res = arr.map(async(item)=>{
return await exportDocx('/word.docx',data);
})
// 这里会拿到10个 Promise对象,内容是是exportDocx 返回的Blob对象。
const zip = new JSZip() //创建压缩对象
res.forEach(async(ee,index)=>{
const e = await ee
// 将文件存到zip中
zip.file('word.docx',e.out, { base64: true,
compression: 'DEFLATE', // STORE:默认不压缩 DEFLATE:需要压缩
compressionOptions: {
level: 9, // 压缩等级1~9 1压缩速度最快,9最优压缩方式
},
})
})
// 等待res中的Promise状态都完成才执行。
Promise.all(res).then(() => {
console.log('zip', zip)
zip
.generateAsync({
type: 'blob',
})
.then((content) => {
FileSaver.saveAs(content, '详情.zip')
this.load = false
})
.finally(() => {})
})
}
word文档摸板如下: 比较特殊的就是在处理图片时。
{#url0}{%url0}{/url0} 这类似if条件语句。
#table需要table的格式为 table:[{url0:'123',url1:'123',...},{}]
大概就这些了,有什么问题私信哦