docx文件上传java_Java操作Word('docx'), 填充模板文件并转为pdf

这篇博客介绍了如何使用Java处理docx文件,填充模板并转换为PDF。首先,通过pom依赖 poi-tl 和 jacob 实现docx文件操作。然后,利用poi-tl的Map集合和自定义渲染策略动态插入数据到word表格。最后,使用jacob库将编辑好的Word文档转换成PDF格式。
摘要由CSDN通过智能技术生成

Java操作Word('docx'), 填充模板文件并转为pdf

1. pom相关依赖

工具poi-tl (操作word文档模板) + jacob (将操作后的word模板转为pdf)

com.deepoovepoi-tl1.9.1

com.jacobjacob1.17system${project.basedir}/src/main/resources/lib/jacob.jar

2. 对word模板进行插入数据操作

使用poi-tl操作word需要创建一个用于向word插入数据的Map集合, word模板中标签格式为"{{标签}}", 其中标签内容为Map 的key.

// 项目根路径String abPath = new File("").getAbsolutePath() + "/src/main/resources";// 创建用于插入数据的MapMap map = new HashMap<>();map.put(, );...// 填充word文档XWPFTemplate template = XWPFTemplate.compile(abPath + "").render(map);// 输出文档template.writeAndClose(new FileOutPutStream(""));

3. 对word模板的表格执行插入数据操作(动态表格)

使用poi-tl操作word的表格,动态的插入数据,需要用到poi-tl的可选插件进行自定义渲染策略, 首先在word需要操作的表格中的任意单元格添加标签“{{标签}}”

自定义渲染策略

/** * 自定义渲染策略 * * @author */public class DetailTablePolicy extends DynamicTableRenderPolicy { // 表格起始行行数 int tableStartRow = 1; /** * 自定义渲染策略 * * @data 传入的封装好的数据 */ @Override public void render(XWPFTable table, Object data) throws Exception { // 如果数据为空,直接返回 if (null == data) return; // 封装数据List的数据封装对象 NdrwhkhzbData detailData = (NdrwhkhzbData) data;// 获取当前列表行高 int height = table.getRow(2).getHeight(); // 从封装对象中获取数据集合 List datas = detailData.getNdrwhkhzbs(); if (null != datas) { // 循环移除空白表格中数据数量的空白行 for (int i = 1; i < datas.size() + 2; i++) { table.removeRow(i); } // 循环插入数据 for (int i = 0; i < datas.size(); i++) { // 新增一行空白行 XWPFTableRow insertNewTableRow = table.insertNewTableRow(tableStartRow); // 设置行高 insertNewTableRow.setHeight(height); // 循环添加单元格(4为每行单元格数量) for (int j = 0; j < 4; j++) { insertNewTableRow.createCell(); } // 填充表格 TableRenderPolicy.Helper.renderRow(table.getRow(tableStartRow), datas.get(i)); } } }}

把自定义渲染策略当做工具类, 在主逻辑中直接配置使用

/** * 操作年度任务和考核指标表 * * @throws IOException 输入输出流异常 */ private void createNdrwhkhzb(Integer uid, String dirPath) throws IOException { PageData datas = new PageData(); NdrwhkhzbData detailTable = new NdrwhkhzbData(); List nds = new ArrayList<>(); // 根据uid查询年度任务和考核指标数据 List list = ndrwhkhzbService.selectNdrwhkhzbByUid(uid); for (NdrwhkhzbEntity ndrwhkhzbEntity : list) { RowRenderData rrd = Rows.of(ndrwhkhzbEntity.getNd(), ndrwhkhzbEntity.getNdrw(), ndrwhkhzbEntity.getNdkhzb() , ndrwhkhzbEntity.getZyrwdsjjd()).center().create(); nds.add(rrd); } detailTable.setNdrwhkhzbs(nds); datas.setNdrwhkhzbData(detailTable); // 配置表格 Configure config = Configure.builder().bind("detail_table", new DetailTablePolicy()).build(); // 调用渲染策略进行填充 XWPFTemplate template = XWPFTemplate.compile(dirPath + "/" + uid + "_Complete.docx", config).render(datas); // 写入表格中 template.writeToFile(dirPath + "/" + uid + "_Complete.docx"); }

用到的一些实体类

// PageDatapublic class PageData { @Name("detail_table") private NdrwhkhzbData ndrwhkhzbData; public NdrwhkhzbData getNdrwhkhzbData() { return ndrwhkhzbData; } public void setNdrwhkhzbData(NdrwhkhzbData ndrwhkhzbData) { this.ndrwhkhzbData = ndrwhkhzbData; }}// NdrwhkhzbDatapublic class NdrwhkhzbData { private List ndrwhkhzbs; public List getNdrwhkhzbs() { return ndrwhkhzbs; } public void setNdrwhkhzbs(List ndrwhkhzbs) { this.ndrwhkhzbs = ndrwhkhzbs; }}

4. 将编辑好的Word转为pdf格式(jacob)

这里将word转为pdf时需要用到jacob, 这里需要将jacob的dll文件放到jdk和jre的bin目录下, 下载的jacob中dll文件一般为两个版本, X86为32位, X64为64位, 根据自己安装的jdk版本添加所对应的dll文件

/** 将 .docx 转换为 .pdf*/ ActiveXComponent app = null; String wordFile = dirPath + "/" + uid + "_Complete.docx"; String pdfFile = dirPath + "/" + dirName + ".pdf"; System.out.println("开始转换..."); // 开始时间 long start = System.currentTimeMillis(); try { // 打开word app = new ActiveXComponent("Word.Application"); // 设置word不可见,很多博客下面这里都写了这一句话,其实是没有必要的,因为默认就是不可见的,如果设置可见就是会打开一个word文档,对于转化为pdf明显是没有必要的 //app.setProperty("Visible", false); // 获得word中所有打开的文档 Dispatch documents = app.getProperty("Documents").toDispatch(); System.out.println("打开文件: " + wordFile); // 打开文档 Dispatch documentP = Dispatch.call(documents, "Open", wordFile, false, true).toDispatch(); // 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在 File target = new File(pdfFile); if (target.exists()) { target.delete(); } System.out.println("另存为: " + pdfFile); // 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17 Dispatch.call(documentP, "SaveAs", pdfFile, 17); // 关闭文档 Dispatch.call(documentP, "Close", false); // 结束时间 long end = System.currentTimeMillis(); System.out.println("转换成功,用时:" + (end - start) + "ms"); } catch (Exception e) { e.getMessage(); System.out.println("转换失败" + e.getMessage()); } finally { // 关闭office app.invoke("Quit", 0); }

5. 通过lo流将生成好的文件传到浏览器下载

/* * 下载pdf */String fileName = dirName + ".pdf";File file = new File(dirPath + "/" + fileName);if (file.exists()) { BufferedInputStream bis = null; FileInputStream fis = null; try { response.setHeader("Content-disposition", "attachment; filename=" + fileName); byte[] buff = new byte[2048]; fis = new FileInputStream(file); bis = new BufferedInputStream(fis); OutputStream os = response.getOutputStream(); int i = bis.read(buff); while (i != -1) { os.write(buff, 0, i); i = bis.read(buff); } os.close(); } catch (Exception e) { e.printStackTrace(); } finally { assert fis != null; fis.close(); assert bis != null; bis.close(); }}

6. 最后的Controller整体代码

package org.example.controller;import com.deepoove.poi.XWPFTemplate;import com.deepoove.poi.config.Configure;import com.deepoove.poi.data.Includes;import com.deepoove.poi.data.RowRenderData;import com.deepoove.poi.data.Rows;import com.jacob.activeX.ActiveXComponent;import com.jacob.com.Dispatch;import org.example.entity.*;import org.example.service.*;import org.example.utils.DetailTablePolicy;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;import org.springframework.util.DigestUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.*;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * 创建pdf控制器 * * @author: yoojyn * @data: 2021/1/11 */@Controller@RequestMapping("/createPdfController")public class CreatePdfController { @Autowired private IKtfmService ktfmService; @Autowired private IKtjbxxService ktjbxxService; @Autowired private IKtbyxfxService .........

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值