1. pom相关依赖

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

com.deepoove

poi-tl

1.9.1

com.jacob

jacob

1.17

system

${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";

// 创建用于插入数据的Map

Map 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");

}

用到的一些实体类

// PageData

public class PageData {

@Name("detail_table")

private NdrwhkhzbData ndrwhkhzbData;

public NdrwhkhzbData getNdrwhkhzbData() {

return ndrwhkhzbData;

}

public void setNdrwhkhzbData(NdrwhkhzbData ndrwhkhzbData) {

this.ndrwhkhzbData = ndrwhkhzbData;

}

}

// NdrwhkhzbData

public 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 ktbyxfxService;

@Autowired

private IZtmbhkhzbService ztmbhkhzbService;

@Autowired

private INdrwhkhzbService ndrwhkhzbService;

@Autowired

private IKtjfysjsmService ktjfysjsmService;

@Autowired

private IXjxhkxxfxService xjxhkxxfxService;

/**

* 生成word文件

*

* @param session 作用域

*/

@Scope("prototype")

@ResponseBody

@RequestMapping("/createPdf")

public void createPdf(HttpSession session, HttpServletResponse response) {

// 获取当前用户id

Userinfo loginedUser = (Userinfo) session.getAttribute("loginedUser");

Integer uid = loginedUser.getUid();

String dirName = DigestUtils.md5DigestAsHex((uid + "_国家重大专项任务合同申报").getBytes());

String dirPath = "D:/" + dirName;

String abPath = new File("").getAbsolutePath() + "/src/main/resources";

try {

// 创建用于存储中间文件的文件夹

new File(dirPath).mkdirs();

// 创建用于存储数据的map集合

Map map = new HashMap<>();

// 获取封面数据

createKtfm(uid, map);

// 获取基本信息数据

createJbxx(uid, map);

// 获取必要性分析

createByxfx(uid, map);

// 获取总体目标和考核指标

createZtmbhkhzb(uid, map);

// 获取经费预算及说明

createJfysjsm(uid, map);

// 查询附件

XjxhkxxfxEntity xjxhkxxfxEntity = xjxhkxxfxService.selectXjxhkxxfxByUid(uid);

// 设置下一步处理表格要用到的标签

map.put("page9",

Includes.ofLocal(abPath + "/static/file/upload/" + xjxhkxxfxEntity.getFilename()).create());

map.put("detail_table", "{{detail_table}}");

// 填充文档

XWPFTemplate template = XWPFTemplate.compile(abPath + "/static/file/moban/moban.docx").render(map);

// 输出文档

template.writeAndClose(new FileOutputStream(dirPath + "/" + uid + "_Complete.docx"));

// 操作年度任务和考核指标表

createNdrwhkhzb(uid, dirPath);

} catch (IOException e) {

e.printStackTrace();

}

try {

/*

* 将 .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);

}

/*

* 下载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();

}

}

} catch (Exception e) {

e.printStackTrace();

} finally {

delDir(new File(dirPath));

}

}

/**

* 删除文件夹

*

* @param file 文件夹对象

*/

private void delDir(File file) {

if (file.isFile()) {

file.delete();

}

if (file.isDirectory()) {

File[] files = file.listFiles();

for (File f : files) {

f.delete();

}

file.delete();

}

}

/**

* 储存经费预算及说明

*

* @param uid 用户id

* @param map 储存数据的map集合

*/

private void createJfysjsm(Integer uid, Map map) {

// 根据用户编号查询经费预算及说明

KtjfysjsmEntity ktjfysjsmEntity = ktjfysjsmService.getDatesByUid(uid);

// 添加到map集合

map.put("zjzyczzj", ktjfysjsmEntity.getZjzyczzj());

map.put("zjdfczzj", ktjfysjsmEntity.getZjdfczzj());

map.put("zjdwzczj", ktjfysjsmEntity.getZjdwzczj());

map.put("zjqt", ktjfysjsmEntity.getZjqt());

}

/**

* 操作年度任务和考核指标表

*

* @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");

}

/**

* 储存总体目标和考核指标

*

* @param uid 用户id

* @param map 储存数据的map集合

*/

private void createZtmbhkhzb(Integer uid, Map map) {

// 根据用户编号查询总体目标和考核指标

ZtmbhkhzbEntity ztmbhkhzbEntity = ztmbhkhzbService.selectZtmbhkhzbByUid(uid);

// 添加到map集合

map.put("page6", ztmbhkhzbEntity.getZtmbhkhzb());

}

/**

* 储存必要性分析数据

*

* @param uid 用户id

* @param map 储存数据的map集合

*/

private void createByxfx(Integer uid, Map map) {

// 根据用户编号查询必要性分析数据

KtbyxfxEntityWithBLOBs ktbyxfxEntity = ktbyxfxService.selectKtbyxfxByUid(uid);

// 添加到map集合

map.put("page5_ktyzx", ktbyxfxEntity.getKtyzx());

map.put("page5_ktysfgc", ktbyxfxEntity.getKtysf());

map.put("page5_ktyq", ktbyxfxEntity.getKtyq());

}

/**

* 储存基本信息数据

*

* @param uid 用户编号

* @param map 储存数据的map集合

*/

private void createJbxx(Integer uid, Map map) {

// 根据用户编号查询基本信息数据

KcjbxxEntity kcjbxxEntity = ktjbxxService.selectKtjbxxByUid(uid);

// 添加到map集合

map.put("page3_ktmc", kcjbxxEntity.getKtmc());

map.put("page3_ktmj", kcjbxxEntity.getKtmj());

map.put("page3_yjwcsj", kcjbxxEntity.getYjwcsj());

map.put("page3_kyhdlx", kcjbxxEntity.getKthdlx());

map.put("page3_yqcglx", kcjbxxEntity.getYqcglx());

map.put("page3_dwmc", kcjbxxEntity.getDwmc());

map.put("page3_dwxz", kcjbxxEntity.getDwxz());

map.put("page3_txdz", kcjbxxEntity.getTxdz());

map.put("page3_yzbm", kcjbxxEntity.getYzbm());

map.put("page3_szdq", kcjbxxEntity.getSzdq());

map.put("page3_dwzgbm", kcjbxxEntity.getDwzgbm());

map.put("page3_lxdh", kcjbxxEntity.getLxdh());

map.put("page3_zzjgdm", kcjbxxEntity.getZzjgdm());

map.put("page3_czhm", kcjbxxEntity.getCzhm());

map.put("page3_dwclsj", kcjbxxEntity.getDwclsj());

map.put("page3_dzxx", kcjbxxEntity.getDzxx());

}

/**

* 储存课题封面数据

*

* @param uid 用户编号

* @param map 储存数据的map集合

*/

private void createKtfm(Integer uid, Map map) {

// 根据用户编号查询封面数据

KtfmEntity ktfmEntity = ktfmService.selectKtfmByUid(uid);

// 添加到map集合

map.put("page1_zxmc", "5G总体及关键器件");

map.put("page1_xmbh", "2016ZX03001_001");

map.put("page1_xmmc", "新一代宽带无线移动通信网");

map.put("page1_ktbh", "2016ZX03001_001_002");

map.put("page1_ktmc", "5G高性能基站A/D、D/A转换器试验样片研发");

map.put("page1_zrdw", "program_test");

map.put("page1_ktzz", ktfmEntity.getKtfzr());

map.put("page1_ktnx1", "2016-01-01");

map.put("page1_ktnx2", "2017-12-31");

map.put("page1_tbrq", "2020-12-28");

map.put("page1_nian", "二一");

map.put("page1_yue", "一");

}

}

以上就是Java 实现word模板转为pdf的详细内容,更多关于Java word模板转为pdf的资料请关注脚本之家其它相关文章!

java pdf 转word源码_Java 实现word模板转为pdf相关推荐

  1. java手机小游戏源码_Java手机版数独小游戏(J2me)JAVA游戏源码下载

    数独游戏,相信朋友们都知道的,以前也经常玩的,用VB.VC++和Delphi版编写的都在网上宣布过,今天放出一个鉴于Java的J2me手机版的,大致看一下截图,这是在Java模拟机运行的界面,带有Ja ...

  2. java sso单点登录源码_Java单点登录系统 sso源码下载

    这是一个使用Java开发的单点登陆系统(sso). 运行截图 单点登陆介绍 单点登录,这就是我们通常称之为SSO.一般来说,大型系统平台将使用这些东西.它解决了频繁登录和验证的过程,即用户的一次登录被 ...

  3. java在线学习系统源码_Java在线考试系统源码

    今天给大家演示的是一款由jsp+mysql+ssm框架实现的学生在线考试系统,,今天这个考试系统功能比较完善,支持单选.多选.简答题型,试题可以批量导入,导入时可选择多种方式导入,比如导入到试题库,导 ...

  4. java短信接口源码_java免费短信接口开发源码

    java免费短信接口开发源码 更多 作者:捷信通来源:www.jiexintong.cn日期:2014-07-30 17:08:51 微宏捷信通短信接口提供适应C#.Java..NET等多种主流开发语 ...

  5. java 仿百度文库源码_java开发_模仿百度文库_OpenOffice2PDF_源码下载

    这几天在研究模仿着做类似于百度文库的东西,在这里给大家分享一下我自己做的东西. 由于需要做这样的项目,我查阅了很多资料,最后选定一下方案去做: Txt/Word/Excel/PPT=>PDF(O ...

  6. java在线学习系统源码_java学习成长之路(基础,源码,项目,实战)

    获取一下学习资源请关注微信公众号:Java编程指南 我为自学编程的或初学java的小伙伴们准备了一整套完整的学习资源和文章,还有我自己在自学路上的一些总结和学习线路,希望能帮到小伙伴们,如果有什么疑问 ...

  7. java微信支付接口源码_java微信支付源码(WxPayAPI_JAVA_v3)

    [实例简介] [实例截图] [核心代码] package com.github.wxpay.sdk; import java.util.HashMap; import java.util.Map; i ...

  8. java ftp下载文件源码_java实现ftp文件下载的源代码

    这几天做的一个项目中用到了ftp文件传输,用java实现了ftp文件的下载. 一.win7下搭建ftp服务器 详见:http://jingyan.baidu.com/article/4b52d7026 ...

  9. java读取 info.plist源码_Java 解析 IPA 文件,读取 Info.plist 信息-Go语言中文社区

    在做移动MDM功能的时候,就遇到了这样一个问题,当用户上传IPA文件时,我如何知道这个IPA文件的相关信息呢?IPA文件有一个很重要的文件Info.plist 就类似于Android程序的Manife ...

最新文章

  1. Harmonic Number(调和级数+欧拉常数)
  2. 034_jdbc-mysql-C3P0
  3. apache nginx mysql php_php+Apache2+Nginx+Mysql
  4. vue生成包报错error from UglifyJs
  5. 交叉编译指定运行时库路径_运行时vs编译时类路径
  6. scatter python_Python scatter详解
  7. Swift中文教程(十) 属性
  8. leetcode - 646. 最长数对链
  9. springboot 多线程_机密文档!阿里产出SpringBoot/Cloud,细节爆炸
  10. pytorch教程:save and load
  11. 软件测试人员进阶必读的八大书籍
  12. selenium 在pycharm中安装selenium
  13. 离散Hopfield神经网络的联想记忆——数字识别
  14. WebCracker4.0和monster字典——路由器登陆密码破解工具
  15. Unity 武器拖尾效果
  16. Python开发——8.模块
  17. matlab中的高阶导数,MATLAB如何求函数的n阶导数?
  18. python数据汇总_Python,将数据框中的每日数据汇总到每月和每季度
  19. fastdfs磁盘满,如何清除文件?
  20. 全球移动通信系统GSM(2G)

热门文章

  1. 晨曦记账本记账,使用项目查看账目
  2. 计算机组成原理复试面试高频问题,研究生复试面试高频问题及回答技巧汇总
  3. 我的世界服务器op在文件夹,我的世界服务器怎么做op
  4. 2021年电气试验免费试题及电气试验模拟考试题
  5. RDD:断点回归的非参数估计及Stata实现
  6. up rom for android,ROMBOTapp下载-ROMBOT安卓版v0.54-upan
  7. Kubernetes(k8s)入门及集群部署文档
  8. Grid++Report 报表开发工具
  9. 浅谈erlang游戏服务器项目--英雄远征服务启动流程
  10. 基于PHP+MySQL+Apache在线考试管理系统(附源码)