当前位置: 首页 > 后端技术 > Node.js

前端使用docxtemplater导出word文档最佳实践

时间:2023-04-03 19:22:02 Node.js

前言作者简介:Quixn,专注Node.js技术栈分享,前端从JavaScript到Node.js。攻略】作者,Github博客开源项目github.com/Quixn...大家好,我是Quixn。最近在做业务系统的时候,遇到一个需求。系统需要导出一个word文档,内容是一个比较复杂的表格。一般业务系统遇到这种需求,后端同学会做导出,前端同学只需要接收文件即可。毕竟这方面有很多成熟的库可以用在后端,但是这方面的开源插件可以用在前端的却很少。没办法,和笔者连接的后端同学刚好经验不足,不会导出word文档。这种情况下,只能靠自己了。google了一圈之后,发现前端只能用一个docxtemplater库,star数2.1k,用起来很便携,也符合这个时候的需要。如果你有其他更好的库推荐,欢迎留言告诉我们。1docxtemplater介绍官网https://docxtemplater.com/GitHubhttps://github.com/open-xml-t...docxtemplater使用JSON数据格式作为输入,可以处理docx和ppt模板。与其他一些工具,如docx.js、docx4j、python-docx等需要自己编写代码生成文件不同,docxtemplater只需要用户编写标签形式的模板来生成文件。2使用Tutorial2.1安装依赖项目需要的依赖:docxtemplater、jszip、jszip-utils、pizzip、file-saver。1.docxtemplater:该插件可以通过预先编写的word、excel等文件模板生成相应的数据文件2.pizzip:该插件用于创建、读取或编辑.zip文件(同步的,也有aplug-in是jszip,异步)3.jszip-utils:与jszip/pizzip一起使用,jszip-utils提供了getBinaryContent(path,data)接口,path是文件的路径,支持AJAX获取请求,数据是读取的文件内容。4.file-saver:适合在客户端生成文件的工具。它提供的接口saveAs(blob,"1.docx")将用于方便地保存文件。5.docxtemplater-image-module-free:如果需要导出图片,需要这个插件npm安装如下:npminstalldocxtemplaterpizzip--save//处理docx模板npminstalljszip-utils--savenpminstalljszip--savenpminstallfile-saver--save//处理输出文件2.2创建word模板文件创建word模板:public/test.docxvuecli3/vuecli4将word模板test.docx存放在公共档案;vuecli2storethewordtemplatetest.docx在静态文件中;如果直接在代码编辑器中新建文件创建test.docx,后面会报错,应该和文件编码格式有关,所以你需要进入项目文件夹,右键新建一个docx文件。编辑好test.docx后,可以在编辑器中编辑看到pulic文件下多了一个~$test.docx文件;这个文件夹基本没问题。2.3docxtemplater语法{%img}image{#list}{/list}循环,if判断{#list}{/list}{^list}{/list}ifelse{str}textdocxtemplater以标签形式填充数据是的,对于简单的数据我们可以使用{}+变量名来实现简单的文本替换。比如:复杂的数据,比如需要打√的多选,需要用到docxtemplater的条件判断语法来实现。实现如下:只有传入的变量category1为true时,才会渲染打√的效果。这时又传入一个变量category_1,取值为category1的倒数。如果整个word文档中有很多这样的需求需要打勾,那么这种实现方式就有一个很大的缺点:需要定义很多变量来控制是否显示打勾。也可以使用if-else语法来实现。笔者还在网上看到了另一种解决方案。笔者尝试了一下,效果并不理想,无法实现需求。你也可以试试。如果您有更好的解决方案,请留言告诉我们。表单需求实现如下:2.4docxtemplater的完整代码实现创建一个exportWordDocx.js文件,定义一个exportWordDocx函数,接收三个入参,demoUrl表示导出的word文档模板路径,docxData表示整合dept、applyDate以及模板文档中定义的其他字段传入docxData即可。fileName表示导出的文件名,切面重命名等操作。将demoUrl传递给JSZipUtils.getBinaryContent方法读取模板文件的二进制内容,然后创建一个内容为模板内容的PizZip实例,然后创建并加载docxtemplater实例对象。使用doc.setData方法设置模板变量的值。对象的key需要和模板上的变量名一样,value就是你要放到模板上的值。这里需要注意一点:如果你在模板上定义的值为null或者undefined,在最终导出的word文档中,相应的地方会直接显示undefined。解决方法:可以将doc.setOptions方法中返回的nullGetter值设置为空。最后通过saveAs方法导出Word文档。从“jszip-utils”导入JSZipUtils;从“docxtemplater”导入docxtemplater;从“file-saver”导入{saveAs};从“pizzip”导入PizZip;导出constexportWordDocx=(demoUrl,docxData,fileName)=>{//读取并获取模板文件的二进制内容JSZipUtils.getBinaryContent(demoUrl,function(error,content){//抛出异常if(error){throwerror;}//使用模板内容创建一个PizZip实例letzip=newPizZip(content);//创建并加载docxtemplater实例对象letdoc=newdocxtemplater().loadZip(zip);//移除undefined值显示的undefineddoc.setOptions({nullGetter:function(){return"";}});//设置angular解析器//设置模板变量的值,对象的key需要和模板上的变量名一样,value就是你的值想放在模板上doc.setData({...docxData,});try{//替换为模板变量的值替换所有模板变量doc.render();}catch(error){//抛出异常console.log(JSON.stringify({error:e}));抛出错误;}//生成一个代表docxtemplater对象的zip文件(不是真实文件,而是内存中的表示)letout=doc.getZip().generate({type:"blob",mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",});//将目标文件对象保存为目标类型的文件,并命名为saveAs(out,fileName);});}3至此,我们使用docxtemplater导出word文档的实践告一段落,实例实现导出功能。欢迎关注,公众号回复【docxtemplater最佳实践】获取文章全部源码。关于我&Node交流群大家好,我是Quixn,专注于Node.js技术栈分享,前端从JavaScript到Node.js,以及后端数据库,优质文章推荐。如果你有兴趣学习Node.js(以下计划也可以),可以关注我,加我微信[Quixn1314],拉你进交流群一起交流学习共建,或者关注公众号【小Q全栈攻略】。Github博客开源项目github.com/Quixn...欢迎加我微信【Quixn1314】,拉你进Node.js进阶进阶群,一起学习Node,长期交流学习...