【word导出带图片】使用docxtemplater导出word,通知书形式的word
一、demo-导出的的
二、代码操作
1、页面呈现
项目要求,所以页面和导出来的word模版一致
2、js代码【直接展示点击导出的js代码】
使用插件【先下载这五个插件,然后页面引入插件】
import docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import ImageModule from 'docxtemplater-image-module-free'
import { saveAs } from 'file-saver'
1>代码
expeortexcel() {
clearTimeout(this.timer) //清除延迟执行
this.faultlist = []
this.faultpic = []
const exportData = this.data
// 处理图片
const crfile = exportData.contractorResponsiblePerson[0].link
const drfile = exportData.drawResponsiblePerson[0].link
if (crfile != '') {
this.UrlToBase64(crfile, (dataURL) => {
exportData['crimg'] = dataURL
})
}
if (drfile != '') {
this.UrlToBase64(drfile, (dataURL) => {
exportData['drimg'] = dataURL
})
}
this.faultlist.push(exportData)
this.timer = setTimeout(() => {
//设置延迟执行
this.export2Word(this.faultlist)
}, 5000)
},
// 处理导出图片数据
UrlToBase64(url, callback) {
console.log(url, 'url===')
let image = new Image()
let that = this
//解决跨域问题
image.setAttribute('crossOrigin', 'anonymous')
image.src = url
image.onload = () => {
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
var quality = 0.8
//这里的dataurl就是base64类型
var dataURL = canvas.toDataURL('image/png', quality)
callback ? callback(dataURL) : null //调用回调函数
}
},
//导出文件
export2Word(faultlistd) {
//v:图片路径,t:时间字符串,name:导出文件名称--变量需自己定制,此处为举例
let self = this
JSZipUtils.getBinaryContent(
window.location.origin + '/tinggong.docx', //需要导出的模板文件地址
function (error, content) {
if (error) {
throw error
}
let zip = new PizZip(content)
let doc = new docxtemplater().loadZip(zip)
// 图片处理
const opts = {}
opts.centered = false // 图片居中,在word模板中定义方式为{%image}
opts.fileType = 'docx'
opts.getImage = (tagValue, tagName) => {
const base64Value = self.base64DataURLToArrayBuffer(tagValue)
if (base64Value) {
return base64Value
}
}
opts.getSize = function (img, tagValue, tagName) {
const sizeOf = require('image-size')
const buffer = Buffer.from(img, 'binary')
const sizeObj = sizeOf(buffer)
const forceWidth = 100
const ratio = forceWidth / sizeObj.width
return [forceWidth, Math.round(sizeObj.height * ratio)]
}
let imageModule = new ImageModule(opts)
doc.attachModule(imageModule)
setTimeout(() => {
doc.setData({
//设置模板数据
// compname: cname,
listfa: faultlistd,
// listimg: faultpicd,
})
try {
doc.render()
} catch (error) {
let e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties,
}
console.log(JSON.stringify({ error: e }))
throw error
}
let out = doc.getZip().generate({
type: 'blob',
mimeType:
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', //导出文件格式
})
saveAs(out, '停工通知书.docx')
}, 4000)
},
)
},
//获取base64格式图片
base64DataURLToArrayBuffer(dataURL) {
const base64Regex = /^data:image\/(png|jpg|svg|svg);base64,/
if (!base64Regex.test(dataURL)) {
return false
}
const stringBase64 = dataURL.replace(base64Regex, '')
let binaryString
if (typeof window !== 'undefined') {
binaryString = window.atob(stringBase64)
} else {
binaryString = Buffer.from(stringBase64, 'base64').toString('binary')
}
const len = binaryString.length
const bytes = new Uint8Array(len)
for (let i = 0; i < len; i++) {
const ascii = binaryString.charCodeAt(i)
bytes[i] = ascii
}
return bytes.buffer
},
1、this.data是接口返回的数据
2、UrlToBase64处理图片数据
3、export2Word导出文件操作
三、通知书模版【毕竟放在public下-且后缀是.docx】
【语法:】
listfa是数组,#开头, /结束
{%drimg} 图片格式前面需要加%
四、拓展docxtemplater语法
官网:Docxtemplater | Word, Powerpoint, Excel generation using templates in your application | docxtemplater
1、基础
Hello {name} ! // 得到 —— Hello John !
{"name": "John"} // 数据格式
2、条件 # 开始 / 结束
{#hasKitty}Cat’s name: {kitty}{/hasKitty}
{#hasDog}Dog’s name: {dog}{/hasDog}{ "hasKitty": true, "kitty": "Minie" "hasDog": false, "dog": null } // 得到Cat’s name: Minie
3、list集合
{#products}
{name}, {price} ¥
{/products}"products": [ { "name": "西服外套", "price": 100 }, { "name": "皮鞋", "price": 200 }, { "name": "劳动力", "price": 0 } ] // 得到 西服外套, 100 ¥ 皮鞋, 200 ¥ 劳动力, 0¥
4、循环遍历一个包含原始数据的数组
{#products} {.} {/products}
"products": ["包子", "饺子", "麻辣烫"] // 得到 包子 饺子 麻辣烫
5、循环展示列表【#开头 /结束】
Name age phone {#users}{name} {age} {phone}{/}
"users": [ { "name": "John", "age": 22, "phone": "+33653454343" }, { "name": "Mary", "age": 25, "phone": "+33666666666" } ]
得到:
Name age phone John 22 +33653454343 Mary 25 +33666666666