1.在pom文件中导入相关依赖

<!--根据模板生成Word 需要依赖 开始--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.jfree</groupId><artifactId>jcommon</artifactId><version>1.0.24</version></dependency><dependency><groupId>org.jfree</groupId><artifactId>jfreechart</artifactId><version>1.5.0</version></dependency><!--根据模板生成Word 需要依赖 结束--><!--word转pdf 需要依赖 开始--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency><dependency><groupId>org.docx4j</groupId><artifactId>docx4j</artifactId><version>6.1.2</version><exclusions><!--生成word的依赖包里 有该依赖了,所以剔除--><exclusion><artifactId>commons-compress</artifactId><groupId>org.apache.commons</groupId></exclusion></exclusions></dependency><dependency><groupId>org.docx4j</groupId><artifactId>docx4j-export-fo</artifactId><version>6.0.0</version></dependency><!--word转pdf 需要依赖 结束-->

2.创建Word模板文件test.docx,设置属性,放入到项目中。

test.docx模板用{{姓名}}符号包起来。


3.新建工具类PdfUtil3

import cn.afterturn.easypoi.word.WordExportUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.springframework.util.Assert;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class PdfUtil3 {private static String separator = File.separator;//文件夹路径分格符/*** 生成word  只支持docx** @param templatePath 模板文件路径* @param temDir 生成文件的目录* @param fileName 生成文件名* @param params 参数*/public static String exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params) {Assert.notNull(templatePath, "模板路径不能为空");Assert.notNull(temDir, "临时文件路径不能为空");Assert.notNull(fileName, "导出文件名不能为空");Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");if (!temDir.endsWith("/")) {temDir = temDir + File.separator;}File dir = new File(temDir);if (!dir.exists()) {dir.mkdirs();}String tmpPath = "";try {XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);tmpPath = temDir + fileName;FileOutputStream fos = new FileOutputStream(tmpPath);doc.write(fos);fos.flush();fos.close();} catch (Exception e) {//e.printStackTrace();}return tmpPath;}public static void downloadFile(HttpServletResponse response,String ID, String NAME) throws UnsupportedEncodingException {String downloadFilePath = "swxxPDF/"+NAME+ID+"事务信息表.pdf";//被下载的文件在服务器中的路径,String fileName =NAME+"的事务信息表.pdf";//被下载文件的名称File file = new File(downloadFilePath);if (file.exists()) {response.setContentType("application/force-download");// 设置强制下载不打开
//            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);//中文名称下载response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));byte[] buffer = new byte[1024];FileInputStream fis = null;BufferedInputStream bis = null;OutputStream outputStream = null;try {fis = new FileInputStream(file);bis = new BufferedInputStream(fis);outputStream = response.getOutputStream();int i = bis.read(buffer);while (i != -1) {outputStream.write(buffer, 0, i);i = bis.read(buffer);}outputStream.flush();} catch (Exception e) {//e.printStackTrace();} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {//e.printStackTrace();}}if (bis != null) {try {bis.close();} catch (IOException e) {//e.printStackTrace();}}if (fis != null) {try {fis.close();} catch (IOException e) {//e.printStackTrace();}}}}}/*** word(docx)转pdf** @param wordPath docx文件路径* @return*/public static String convertDocx2Pdf(String wordPath,String ID,String NAME) {OutputStream os = null;InputStream is = null;try {is = new FileInputStream(new File(wordPath));WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);Mapper fontMapper = new IdentityPlusMapper();fontMapper.put("隶书", PhysicalFonts.get("LiSu"));fontMapper.put("宋体", PhysicalFonts.get("SimSun"));fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));fontMapper.put("黑体", PhysicalFonts.get("SimHei"));fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));mlPackage.setFontMapper(fontMapper);//输出pdf文件路径和名称
//            String fileName = "pdfNoMark_" + System.currentTimeMillis() + ".pdf";
//            String fileName = "事务信息表.pdf";String fileName =NAME+ID+"事务信息表.pdf";//            String pdfNoMarkPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;String pdfNoMarkPath = "swxxPDF/" + separator + fileName;os = new java.io.FileOutputStream(pdfNoMarkPath);//docx4j  docx转pdfFOSettings foSettings = Docx4J.createFOSettings();foSettings.setWmlPackage(mlPackage);Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);is.close();//关闭输入流os.close();//关闭输出流return "";} catch (Exception e) {//e.printStackTrace();try {if (is != null) {is.close();}if (os != null) {os.close();}} catch (Exception ex) {ex.printStackTrace();}} finally {File file = new File(wordPath);if (file != null && file.isFile() && file.exists()) {file.delete();}}return "";}
}

4.Conttroller

@ApiResponses({@ApiResponse(code = 200, message = "成功", response = Activity.class)})@ApiOperation(value = "导出Word的PDF")@GetMapping(value = "/exportWordPDF", produces = "application/octet-stream")public void exportWord(@ApiIgnore MyHttpServletRequestWrapper request, HttpServletResponse response, String affairid) throws UnsupportedEncodingException, UnsupportedEncodingException {SysUserVO user = request.getUser();String ID = user.getSysUserId();Map<String, Object> map = new HashMap<>();//数据库查询字段数据List<Map<String, Object>> listMessageDetail = activityService.getlList(affairid);String sysuserrealname = "  ";String sysusercertificatetype = "  ";if (listMessageDetail.size() > 0) {if (listMessageDetail.get(0).get("sysuserrealname") != null && listMessageDetail.get(0).get("sysuserrealname").toString().length() != 0) {sysuserrealname = listMessageDetail.get(0).get("sysuserrealname").toString();}if (listMessageDetail.get(0).get("sysusercertificatetype") != null && listMessageDetail.get(0).get("sysusercertificatetype").toString().length() != 0) {sysusercertificatetype = listMessageDetail.get(0).get("sysusercertificatetype").toString();}        }map.put("姓名", sysuserrealname);map.put("证件类型", sysusercertificatetype);String filepath = PdfUtil3.exportWord("templates/test.docx", "swxxPDF/", "生成文件.docx", map);PdfUtil3.convertDocx2Pdf(filepath, ID, sysuserrealname);PdfUtil3.downloadFile(response, ID, sysuserrealname);}

4.Excel循环输出

格式:{{$fe:maplist t.时间 t.操作人 t.联系方式 t.操作内容}}
代码查询放入maplist

 List<Map<String, String>> listMapA = new ArrayList<Map<String, String>>();//数据库查询数据List<Map<String, Object>> listMap = activityService.getlLisbllc(affairid);for (int i = 0; i < listMap.size(); i++) {String flowlogtime = "  ";String sysuserrealnameczry = "  ";String sysuserphoneczry = "  ";String flowlogcontentczry = "  ";if (listMap.get(i).get("flowlogtime") != null && listMap.get(i).get("flowlogtime").toString().length() != 0) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");flowlogtime = simpleDateFormat.format(listMap.get(i).get("flowlogtime"));}if (listMap.get(i).get("sysuserrealnameczry") != null && listMap.get(i).get("sysuserrealnameczry").toString().length() != 0) {sysuserrealnameczry = listMap.get(i).get("sysuserrealnameczry").toString();}if (listMap.get(i).get("sysuserphoneczry") != null && listMap.get(i).get("sysuserphoneczry").toString().length() != 0) {sysuserphoneczry = listMap.get(i).get("sysuserphoneczry").toString();}if (listMap.get(i).get("flowlogcontentczry") != null && listMap.get(i).get("flowlogcontentczry").toString().length() != 0) {flowlogcontentczry = listMap.get(i).get("flowlogcontentczry").toString();}Map<String, String> lm = new HashMap<String, String>();lm.put("时间", flowlogtime);lm.put("操作人", sysuserrealnameczry);lm.put("联系方式", sysuserphoneczry);lm.put("操作内容", flowlogcontentczry);listMapA.add(lm);}map.put("maplist", listMapA);map.put("姓名", sysuserrealname);map.put("证件类型", sysusercertificatetype);String filepath = PdfUtil3.exportWord("templates/test.docx", "swxxPDF/", "生成文件.docx", map);PdfUtil3.convertDocx2Pdf(filepath, ID, sysuserrealname);PdfUtil3.downloadFile(response, ID, sysuserrealname)

注意事项
在通过easypoi导出word模板和通过docx4j将导出的word转换成pdf的过程中会出现很多问题,下面将介绍比较重要的几个注意事项。

1.遍历指令的使用
假设有如下的指令,其中一行遍历写在表格中,另一行遍历写在表格外


导出的结果如下,会发现只有表格内的指令生效了

因为easypoi本身是用来导出excel表格的,所以遍历的指令是没有兼容word模板的。

表格中的遍历指令

可以发现表格最后一列应有的数据不见了,而且可以推测数据是被覆盖而不是没有插入。

但是如果在遍历指令的下一行表格中插入数据

可以得出结论表格中如果出现遍历数据,那么同一行的其他数据会被覆盖(包括被空白覆盖)。如果遍历的指令没有写在第一列也是无法生效的。

SpringBoot根据模板生成Word文件,然后Word转PDF相关推荐

  1. springboot结合Freemarker模板生成docx格式的word文档(附代码)

    首先参考的是这篇文章: java利用Freemarker模板生成docx格式的word文档(全过程) - 旁光 - 博客园参考:https://my.oschina.net/u/3737136/blo ...

  2. java利用Freemarker模板生成docx格式的word文档(全过程)

    参考汇总: wordexport: JAVA生成并导出Word文档技术论证 java利用Freemarker模板生成docx格式的word文档(全过程) - 旁光 - 博客园 # 参考资料 - 其他项 ...

  3. Springboot通过模板生成pdf文档带图片

    Springboot通过模板生成pdf文档带图片 环境:springboot2.3.10.RELEASE + itextpdf5.5.13.2 依赖 <dependency><gro ...

  4. Freemark 模板生成doc文件,xml doc文件转docx 文件,docx文件转pdf文件

    freemark 模板生成doc文件,此doc文件为xml格式,无法直接转pdf 需要doc转docx文件,才能转pdf 方法1:docx4j 转 pdf 方法2: e-iceblue docx 转 ...

  5. JAVA 根据模板生成doc文件

    JAVA 根据模板生成doc文件 需求 根据模板生成对应的doc文档,文档内容动态填充. 实现 1.将doc模板转换为ftl文件,放入项目中 1.1 首先将模板另存为xml文件 1.2 更改xml文件 ...

  6. EasyPoi通过模板生成Excel文件

    之前用easypoi实现过导出简单的excel文件,最近又有需求导出固定格式的excel文件,所以在网上搜索学习了一下,现将学会后写的demo记录一下方便以后回顾. 首先照例引入maven依赖(这里版 ...

  7. Springboot —— 根据docx填充生成word文件,并导出pdf

    文章目录 前言 将docx模板填充数据生成doc文件 1.依赖引入 2.doc文件转换docx,并标注别名 3.编写java代码实现数据填充 docx文件填充数据导出pdf(web) 1.依赖引入 2 ...

  8. word 模板生成ftl并实现转换成pdf

    最近在处理doc转换成pdf的时候碰到个比较奇葩的问题,正常的doc文件转换成pdf,使用openoffice,poi,itextpdf,都能进行转换 但是,我需要转换的doc是一个word模板类型的 ...

  9. springboot根据模板生成pdf文件

    前言 最近碰到一个需求,给定一个word/pdf的模板,生成pdf文件,包含pdf文件之间的合并等操作.试了很多种方法(也可能是本人比较菜的原因),只有下面这个方法走通了,做下记录. 文件生成 1 准 ...

最新文章

  1. 一.jquery.datatables.js表格显示
  2. linux安装PHP环境
  3. 我在清华当工程师的日子
  4. DRDB的安装配置与使用(第二版)
  5. 阿里云自带的mysql_阿里云Centos使用自带mysql
  6. 根深才能叶茂:基础软件突破亟待产业界携手创新完善生态
  7. CSS基础——盒子模型【学习笔记】
  8. java前后端分离是否会成为趋势
  9. 神经网络入门之RNN(三)
  10. 获取C#代码执行的时间(精确到毫秒)
  11. Android上使用MP3格式录制声音
  12. 计算机通信网络学什么软件,通信工程专业需要用到的电脑软件有哪些
  13. sql优化的N种方法_持续更新
  14. SNMP:简单网络管理协议(一)
  15. JSP基础教程之表单编辑
  16. ElasticSearch 7.7.0 核心篇
  17. 【Practical】共轭
  18. Android开发项目--跑腿APP-跑儿
  19. es6删除数组某一项_什么时候用集合,什么时候用数组?一文帮你清晰界定
  20. 稳压二极管工作在什么区域?稳压二极管VRWM和VBR是什么?

热门文章

  1. 【机器学习微积分】06 导引:最优化的基本问题和存在条件
  2. 广播 (Broadcast)
  3. matlab premnmx 逆函数,请帮我吧这些数据利用MATLAB premnmx语句进行归一化,高分跪求。...
  4. You will surely observe a Tiffany jewelry
  5. 能上QQ却打不开网页的原因及解决办法
  6. 深入浅出依赖注入及其在抖音直播中的应用
  7. 如何优雅查看Ubuntu的系统信息
  8. 斐波那契回调线怎么画_知行交易学院-新手教学-斐波那契回调线的正确画法(二)...
  9. 遇一人白首 择一居终老
  10. 前端笔记之微信小程序(二){{}}插值和MVVM模式数据双向绑定指令API