vue 向 docx模板中填充数据生成目标docx 文件

这次做了个项目,其中一个模块的功能就是,根据用户填写的信息生成一个pdf

但是pdf有很多表格,而且格式比较复杂,如果用代码写出这种模板,然后将当前页面生成pdf这种方法显然不太现实,后来发现用填充模板的方法可以实现

1.先安装对应依赖

npm install docxtemplater pizzip --save-dev
npm install jszip-utils --save
npm install jszip --save
npm install file-saver --save

2.在src下新建 utils 目录,新建docx.js 文件,并引入依赖包

import Docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'

/**
 4. 导出docx
 5. @param { String } tempDocxPath 模板文件路径
 6. @param { Object } data 文件中传入的数据
 7. @param { String } fileName 导出文件名称
*/
export const exportDocx = (tempDocxPath, data, fileName) => {
  // 读取并获得模板文件的二进制内容
  JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
    if (error) {
      throw error
    }
    const zip = new PizZip(content)
    const doc = new Docxtemplater().loadZip(zip)
    console.log(doc)
    doc.setData(data)
    try {
      // render the document (replace all occurences of {first_name} by John, {last_name} by Doe, ...)
      doc.render()
    } catch (error) {
      const e = {
        message: error.message,
        name: error.name,
        stack: error.stack,
        properties: error.properties
      }
      console.log({
        error: e
      })
      // The error thrown here contains additional information when logged with JSON.stringify (it contains a property object).
      throw error
    }
    const out = doc.getZip().generate({
      type: 'blob',
      mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    }) // Output the document using Data-URI
    saveAs(out, fileName)
  })
}


3.准备模板
在这里插入图片描述
在模板中,将要填充的地方用 {} 包裹一个key值,这就是后面你要传递的数据的key,举例说明
如果你想在联系电话中填充你想填充的号码,此时 你的模板内容 是 {userName},你传递数据的时候就要写成

{userName: '138xxxxxxx'}

这样就可以填充在对应的位置上了

4.使用
首先将准备的docx模板放入 public 文件下下
在这里插入图片描述
注意:一定要放在这个文件下,否则会报错

接着,在页面中引入之前封装好的utils下的js,名字任取,我这里叫exportDocx.js

<template>
  <div class="btn" @click="print">按钮</div>
</template>

<script>
import { exportDocx } from '@/utils/docx.js'
export default {
  components: {},
  data() {
    return {};
  },
  computed: {},
  watch: {},
  methods: {
      print() {
          exportDocx('/templete.docx', {userName: '鸡汤'}, '模版.docx')
      }
  },
  created() {},
  mounted() {},
};
</script>

<style  scoped>
.btn {
    width: 50px;
    height: 50px;
    background-color: pink;
}
</style>

注意这里的

 exportDocx('/templete.docx', {userName: '鸡汤'}, '模版.docx')

注意这里的路径一定是 /templete.docx,我试了几次其他的写法例如相对路径啥的,都会报这个错
在这里插入图片描述
一定是放在public文件下,然后路径写成这样才可以,如果你的vue-cli 版本是2 就放在 static 文件下

这样就可以将你填充的docx模板下载下来

Tip:如果报了这个错
在这里插入图片描述
可以看看这这个
https://bytemeta.vip/repo/open-xml-templating/docxtemplater/issues/632
在这里插入图片描述
docxtemplater 只能处理docx 不能处理 doc格式的文件

检查一下你的模板格式,如果是doc格式需要转换成docx格式

最后如果要生成pdf可以找个插件将word 转换成pdf

要实现Java中的docx模板填充信息,可以使用Apache POI和docx4j这两个开源的库。 使用Apache POI实现模板填充的步骤如下: 1. 创建一个WordDocument对象。 ```java XWPFDocument document = new XWPFDocument(new FileInputStream("template.docx")); ``` 2. 获取文档中的所有段落(Paragraph)和表格(Table)。 ```java List<XWPFParagraph> paragraphs = document.getParagraphs(); List<XWPFTable> tables = document.getTables(); ``` 3. 遍历所有段落和表格,找到需要填充数据的位置,并将数据填充上去。 ```java for (XWPFParagraph paragraph : paragraphs) { String text = paragraph.getText(); if (text != null && text.contains("{{name}}")) { text = text.replace("{{name}}", "张三"); paragraph.setText(text); } } for (XWPFTable table : tables) { List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { String text = cell.getText(); if (text != null && text.contains("{{age}}")) { text = text.replace("{{age}}", "20"); cell.setText(text); } } } } ``` 4.填充好数据的Word文档保存到文件中。 ```java FileOutputStream outputStream = new FileOutputStream("output.docx"); document.write(outputStream); ``` 使用docx4j实现模板填充的步骤如下: 1. 创建一个WordprocessingMLPackage对象。 ```java WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File("template.docx")); ``` 2. 获取文档中的所有段落(P)和表格(T)。 ```java List<Object> paragraphs = wordMLPackage.getMainDocumentPart().getContent(); ``` 3. 遍历所有段落和表格,找到需要填充数据的位置,并将数据填充上去。 ```java for (Object paragraph : paragraphs) { if (paragraph instanceof P) { P p = (P) paragraph; List<Object> runs = p.getContent(); for (Object run : runs) { if (run instanceof Text) { Text text = (Text) run; String value = text.getValue(); if (value != null && value.contains("{{name}}")) { value = value.replace("{{name}}", "张三"); text.setValue(value); } } } } else if (paragraph instanceof Tbl) { Tbl tbl = (Tbl) paragraph; List<Object> rows = tbl.getContent(); for (Object row : rows) { Tr tr = (Tr) row; List<Object> cells = tr.getContent(); for (Object cell : cells) { Tc tc = (Tc) cell; List<Object> paragraphsInCell = tc.getContent(); for (Object paragraphInCell : paragraphsInCell) { if (paragraphInCell instanceof P) { P p = (P) paragraphInCell; List<Object> runs = p.getContent(); for (Object run : runs) { if (run instanceof Text) { Text text = (Text) run; String value = text.getValue(); if (value != null && value.contains("{{age}}")) { value = value.replace("{{age}}", "20"); text.setValue(value); } } } } } } } } } ``` 4.填充好数据的Word文档保存到文件中。 ```java wordMLPackage.save(new File("output.docx")); ``` 以上是使用Apache POI和docx4j两个库实现Java中的docx模板填充信息的方法,你可以根据自己的需求选择其中一种方式来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值