使用工具:html-docx
优势:图片、图表能直接预览并转为base64导出,省去后端难以实现图表的生成后插入的麻烦
劣势:适合一些简单的word模板导出(比如只有标题正文简单的表格图表图片的文档),复杂的可以直接忽略。比如:纸张大小、纸张方向、css大部分样式等等(经本人试验导出无法生成,如有大佬可以配置实现欢迎指正)
下载引入
npm install html-docx-js
npm install file-saver
// 引入import htmlDocx from'html-docx-js/dist/html-docx'import saveAs from'file-saver'
在创建的盒子内完成html代码
<div class="export-box"><!-- html --></div><button @click="gohtml">生成word</button>
生成word导出参考https://blog.csdn.net/Liuer_Qin/article/details/124799876
gohtml(){const app = document.querySelector('.export-box')const cloneApp = app.cloneNode(true)const canvases = app.getElementsByTagName('canvas')const cloneCanvases = cloneApp.getElementsByTagName('canvas')const promises = Array.from(canvases).map((ca, index)=>{returnnewPromise((res)=>{const url = ca.toDataURL('image/png',1)const img =newImage()
img.onload=()=>{URL.revokeObjectURL(url)res()}
img.src = url
// 生成img插入clone的dom的canvas之前
cloneCanvases[index].parentNode.insertBefore(img, cloneCanvases[index])})})// 移除原来的canvasconst cloneCanvas = cloneApp.getElementsByTagName('canvas')
Array.from(cloneCanvas).forEach((ca)=> ca.parentNode.removeChild(ca))
Promise.all(promises).then(()=>{this.convertImagesToBase64(cloneApp)// console.log(document.head.outerHTML)const converted = htmlDocx.asBlob(`
<html xmlns:o=\'urn:schemas-microsoft-com:office:office\' xmlns:w=\'urn:schemas-microsoft-com:office:word\' xmlns=\'http://www.w3.org/TR/REC-html40\'><head><style>
${document.head.outerHTML}
</head>
<body>
${cloneApp.outerHTML}
</body>
</html>`)saveAs(converted,'test.docx')})},convertImagesToBase64(cloneApp){var regularImages = cloneApp.getElementsByTagName('img')var canvas = document.createElement('canvas')var ctx = canvas.getContext('2d')
regularImages.forEach((item)=>{
canvas.width = item.width
canvas.height = item.height
ctx.drawImage(item,0,0, item.width, item.height)var ext = item.src.substring(item.src.lastIndexOf('.')+1).toLowerCase()var dataURL = canvas.toDataURL('image/'+ ext)
item.setAttribute('src', dataURL)})
canvas.remove()}
页面及导出效果
最后补充一下,项目本准备开始采用这种方案来实现的,但是功能还是有些欠缺了,尤其纸张大小和横版显示,不得不放弃了这种方式。因为图表的问题,最后是前端先请求数据再页面隐藏位置生成图表,按base64或者文件传送的方式传给后端,仍然由后端生成word返回文件流进行导出。
综上,如何模板内容格式简单,要求低,纯前端来实现这种预览导出还是可行的,要求高的话还是后端去做吧。
版权归原作者 在车上在路上 所有, 如有侵权,请联系我们删除。