首页>>前端>>JavaScript->【实战分享】js生成word(docx),以及将word转成pdf解决方案分享

【实战分享】js生成word(docx),以及将word转成pdf解决方案分享

时间:2023-11-30 本站 点击:0

本文将记录如何用js生成word文件,并在node服务器端将word转换成pdf。记录的代码均是在真实业务场景中使用成功的代码,没有记录中间踩坑的过程。想直接抄答案的家人们可以跳转到1.2 程序编写部分,最终效果图可在1.2 程序编写部分中4. 效果展示模块查看。

如果有更好的解决方案,也欢迎大家在评论区讨论、分享~

本文demo存放地址:https://github.com/ChicKo1108/docxtemplater-demo

一、DocxTemplater:使用js生成word

老铁们,话不多说,先上链接:Docxtemplater | Word, Powerpoint, Excel generation using templates in your application | docxtemplater

DocxTemplater是一个基于模板生成最终文件的插件,它通过一个简单的{tag}语法将预设的数据填入模板Word或者Powerpoint中,帮助开发者快速生成最终文件。

由于DocxTemplater是基于{tag}变量替换,得到最终的文件,因此文件的样式是非常可控的。在开发过程中,设计师只需要出一版最终的成品word,开发者将内容替换成对应的{tag}即可(再也不用被设计师追着还原设计稿了!)。

DocxTemplater是一个收费的库,但是它拥有免费的开源版本,对于我所涉及的业务,使用免费版本完全可以解决。

开源版包括的功能包括:

{tag}替换

条件判断

循环

图片渲染

除免费版外,它还拥有pro plan(950€ per\year)Entreprise plan(24500€ per\year),具体功能大家可以前往官网查看。(但是白嫖的永远是最香的!)

由于我的业务只涉及生成word和pdf,所以本文只介绍word的相关内容,如果需要处理ppt,大家可前往官网自行学习。

1.1 模板语法

在了解模板语法之前,我们需要先创建一个tempalte.docx模板文件。

变量替换

变量使用{key}标签,在tempalte.docx文件中输入以下模板:

Hello, my name is {name}.

然后准备以下数据:

let data = {    name: "千万",}

最终我们生成的docx文件将会是:

Hello, my name is 千万.

条件判断

条件判断使用{#key}开始,使用{/key}结束,最简单的用法是使用Boolean类型数据进行填充。

Hello, my name is {name}.{#hasAge}I'm {age} years old.{/hasAge}{#hasWeight}My weight is {weight}.{/hasWeight}

然后准备以下数据:

let data = {    name: "千万",    hasAge: true,    age: 23,    hasWeight: false,}

最终我们生成的docx文件将会是:

Hello, my name is 千万.I'm 23 years old.

除了Boolean类型的数据以外,我们也可以填充其他类型:

type是否显示模块false / 空数组不显示非空数组显示,且将循环渲染内部元素对象显示,且使用对象内部变量替换{tag}其他真值显示

如果变量填充了数组,其实就是我们下面要介绍的循环语法,在下面一小节中再进行介绍。

在这里简单说一下填充对象的情况:

准备word模板如下:

总价格:{price}{#product} ${productName}: ${price} {/product}

准备数据如下:

let data = {    price: 159,    product: {        productName: 'pencel',        price: 1.2    }}

最终我们生成的docx文件将会是:

总价格:159pencel:$1.2

循环

循环的标志与条件判断相同,但对应的变量应使用Array来填充。

{#examScoreList}    {exam}: {score}{/examScoreList}

然后我们填充以下数据:

let data = {    name: "千万",}0

最终我们生成的docx文件将会是:

let data = {    name: "千万",}1

表格循环

值得注意的是,循环不仅仅可以循环一段普通文字,我们也可以对表格进行循环,包括:循环行和循环整个表。如果想要循环渲染多个表格,只需要在表格外面使用循环语法即可,不在此处过多赘述。下面展示循环渲染一个表中的行的写法:

上图中可以看到,我在表格的第二行中使用了循环语法进行填写,这样我们最终生成的文档中,表头和尾就不会被循环,第二行将会被多次渲染,结果如下:

图片

图片使用{%image}进行标注即可,对于图片的数据传入需要特殊处理,后面的部分会进行介绍。

总结

根据以上语法,我们就可以准备对应的word模板文件了,大部分场景下应该都可以满足。在准备模板的时候,固定的文案和样式直接保留在文档中即可,包括页眉、页脚,各个段落的行距、间距,文字的字体、大小等。其他需要根据真实数据渲染的值,就用标签标注上。准备好模板文件以后,就可以开始脚本函数的编写了。

PS: 要善用表格进行排版布局!

1.2 程序编写

安装所需库

let data = {    name: "千万",}2

客户端生成

1. 获取模板文件的binaryString

let data = {    name: "千万",}3

这里使用到了FileReader类,用于将模板文件转换为binaryString,需要注意浏览器的兼容性。

如果对兼容性有要求,可以是使用pizzip/utils中提供的方法getBinaryContent,但是此库对ts兼容性比较差,因此我在实际代码中使用了FileReader

let data = {    name: "千万",}4

2. 生成最终文件(无需图片)

let data = {    name: "千万",}5

3. 准备数据,生成最终文件

接下来我们准备一个<input type="file" />的文件输入框(你也可以使用网络请求,或者任何方式拿到文件,只要最终获得二进制数据就可以),用来获取模板文件。同时准备好相应的数据,来对模板进行填充。

let data = {    name: "千万",}6

4. 效果展示

模板文件如下:

生成结果如下:

5. 图片处理

如果需要在模板中使用图片,我们需要安装docxtemplater-image-module-free模块。

引入了此模块后,需要在加载模板文件后,载入image模块,然后异步填入数据。

let data = {    name: "千万",}7

对于有图片的文档生成,需要异步载入数据,且图片数据需要处理为base64,上述代码给出了处理图片的一种解决方案,如果大家有更高效的方法也可以自行使用。

node服务器端生成

该库同样支持在node中使用,其思想与在浏览器端基本一致,在node端可以直接使用buffer,下面贴出官方给出的代码示例。

let data = {    name: "千万",}8

1.3 总结

docxTemplater是一个通过模板文件生成word的库,它能最大程度的保证最终生成的word的样式的完整和还原。代码搭建好后,对于类似的业务,开发者们只需要编写更多的模板文件,并且把精力集中在对数据的处理上即可。

配合e-charts或其他图表库,也可以让我们实现报表文件的生成。

此外,对于pizzip这个库,它本身是对jszip库的一个升级,拥有对zip文件的操作能力,可以直接解压或者生成zip包,我们可以直接通过此库对批量生成的文件进行打包处理,打包主要用的api如下:

let data = {    name: "千万",}9

二、使用libre office将word转换成pdf

在进行此部分业务时,原本想在前端把所有的工作都做好,但是没有找到在客户端就直接转换的方法。因此,此部分在服务器端进行解决。

首先需要在机器上安装libre office软件,具体方法可以自行搜索。

安装好后,项目中安装libreoffice-convert库,这个库对libre office的转换方法进行了封装,直接调用其中方法就好:

Hello, my name is 千万.0

如果是zip文件,同样可以安装jsZip或者pizZip进行解压、打包等处理。这里更推荐使用jsZip,因为文档更加丰富,且对ts支持更好。

三、结束语

这是我第二次遇到此类业务,所以本着学习、记录、分享的心态,将内容分享到平台上。在开发过程中遇到了很多“坑”,并没有在本文中记录。本文主要还是以记录最终成功的代码为主,把内容分享给其他有同样需求的家人们。毕竟轮子已经这么完善了,当然要好好利用啦!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/JavaScript/3968.html