前言:客户要求导出某功能里面的图片,于是乎想着用PDF导出,但无奈,图片是在太多了,PDF多页的时候,图片被截断(一部分在上一页,一部分在下一页),不停的调试代码处理这个,着实难以处理,最后只好放弃,换成word导出,依靠word文档的当前页装不下,自动放到下一页去。
导出word文档方法有很多,但这次要导出图片,所以选用了html-docx
html-docx是根据html代码进行导出
先引入html-docx
npm install html-docx --save
具体功能引入
import htmlDocx from 'html-docx'
但我这边是下载html-docx.js文件放在项目里面了,具体是引入还是下载js文件再引入看各自操作吧,js文件我放在文章里面,可以下载。
我的写法如下:
import { asBlob } from 'htmlDocx.js文件存放路径'
先在HTML上面定义个DOM结构,作为导出格式,由于我只导出图片和一个标题,所以简单点了
<!-- 导出Word使用, 样式自己定义,但一定要定义id或者ref,方便后期取到DOM结构 --> <!-- exportWordList 是要导出的数据,这里遍历它显示出来 --> <!-- 加个v-show隐藏起来,不让用户看到 --> <div ref="voucherWord" id="voucherWord" class="" v-show="false"> <div v-for="(item, index) in exportWordList" :key="index"> <!-- 标题 --> <div style="font-size: 15px; font-weight: bold;" class="">{{ item.title }}</div> <!-- 图片 --> <img v-if="item.imgList.length" v-for="(url, imgIndex) in item.imgList" :key="imgIndex" class="item img-x" :src="url" /> </div> </div>
导出方法
// 导出Word async onExportWord () { // 将要要导出的数据 const exportList = [] // 处理后的导出数据 const handlerExportList = [] // 图片字段 const imgFieldList = ['img', 'img1',.....] for (let index = 0; index <= exportList.length; index++) { // 当前行 const row = exportList[index] // 图片base64集合 const imgBa64List = [] // 过滤出当前行图片字段有值的 const currentRowImgFieldList = imgFieldList.filter(e => row[e]) // 遍历图片字段 for (let ai = 0; ai < currentRowImgFieldList.length; ai++) { const imgField = currentRowImgFieldList[ai] // 图片字段值,一个完成的url const url = row[imgField] // 根据url把图片转换成base64编码,这里加了await, 方法名前面必须得加async,把这个imageToBase64方法变成同步方法,imageToBase64方法后面再贴出来 // 我的图片是随意排序,所以这里直接push base64的值了 imgBa64List.push(await imageToBase64(url)) } handlerExportList.push({ title: row.title, imgList: imgBa64List }) } this.exportWordList = handlerExportList // 等待HTML的DOM结构渲染完成 this.$nextTick(() => { // 在等1.5秒,避免图片没有渲染完成 setTimeout(() => { // 导出word文档 // 取ref为voucherWord的DOM结构 const htmlString = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> ${this.$refs.voucherWord.innerHTML} </body> </html> ` // 用html-docx.js的asBlob方法把html结构转成word文档blob格式 const blob = asBlob(htmlString) // 导出word,这里获得了blob,有很多种导出方法,可以用FileSaver.js(百度一下就有了),我这里就简单点了,用HTML的A标签导出 // 获取下载链接 const url = URL.createObjectURL(blob) // 页面上有一个a标签,A标签设置一下id或者ref,反正这里获取它的dom结构,用于下载Excel使用 this.$refs.downloadFile.href = url // 设置excel名称 this.$refs.downloadFile.download = '测试导出.docx' // 模拟点击一次a标签,执行下载 this.$refs.downloadFile.click() // 清空要导出的数据 setTimeout(() => this.exportWordList = [], 1000) }, 1500) }) }
图片URL转base64方法(imageToBase64)
imageToBase64 (url, width, height) { return new Promise((resolve, reject) => { const image = new Image() image.src = url image.crossOrigin = '*' image.onload = () => { const canvas = document.createElement('canvas') canvas.width = width || image.width canvas.height = height || image.height const ctx = canvas.getContext('2d') ctx.drawImage(image, 0, 0, width || image.width, height || image.height) const base64 = canvas.toDataURL('image/png') resolve(base64) } }) }
有需要excel导出图片的,可以看我另一篇文章
前端(vue)exceljs导出Excel(导出图片)https://blog.csdn.net/new_public/article/details/135657768
码字不易,于你有利,勿忘点赞
人生得意须尽欢,莫使金樽空对月