用java写一段通过word模板生成docx文件并转pdf的代码并可通过浏览器下载

时间: 2024-05-13 16:14:11 浏览: 10
以下是一个通过Word模板生成DOCX文件并转换为PDF,并提供浏览器下载的Java代码示例: ```java import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.docx4j.Docx4J; import org.docx4j.convert.out.pdf.PdfConversion; import org.docx4j.convert.out.pdf.viaXSLFO.ConversionOptions; import org.docx4j.fonts.IdentityPlusMapper; import org.docx4j.fonts.Mapper; import org.docx4j.model.structure.PageSizePaper; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.docx4j.wml.CTBorder; import org.docx4j.wml.CTBorderPr; import org.docx4j.wml.CTTbl; import org.docx4j.wml.CTTblBorders; import org.docx4j.wml.CTTblGrid; import org.docx4j.wml.CTTblLayoutType; import org.docx4j.wml.CTTblPr; import org.docx4j.wml.CTTblWidth; import org.docx4j.wml.ObjectFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class WordToPdfController { @RequestMapping(value = "/word-to-pdf", method = RequestMethod.GET) public void generatePdf(HttpServletResponse response) throws Exception { // 获取Word模板文件 File templateFile = new File("template.docx"); FileInputStream in = new FileInputStream(templateFile); // 替换Word中的变量 Map<String, String> variables = new HashMap<>(); variables.put("name", "John Doe"); variables.put("age", "30"); variables.put("address", "123 Main Street"); byte[] docxBytes = replaceVariables(in, variables); // 将DOCX文件转换为PDF byte[] pdfBytes = convertToPdf(docxBytes); // 设置响应头 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=output.pdf"); // 将PDF文件写入响应体 OutputStream out = response.getOutputStream(); out.write(pdfBytes); out.flush(); out.close(); } private byte[] replaceVariables(InputStream in, Map<String, String> variables) throws Exception { // 加载Word模板文件 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in); MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart(); // 获取文档中的所有段落和表格 java.util.List<Object> paragraphsAndTables = documentPart.getContent(); // 遍历文档中的所有段落和表格 for(Object paragraphOrTable : paragraphsAndTables) { if(paragraphOrTable instanceof XWPFParagraph) { // 如果是段落,则替换其中的变量 XWPFParagraph paragraph = (XWPFParagraph) paragraphOrTable; for(XWPFRun run : paragraph.getRuns()) { String text = run.getText(0); if(text != null) { for(Map.Entry<String, String> entry : variables.entrySet()) { if(text.contains(entry.getKey())) { text = text.replace(entry.getKey(), entry.getValue()); run.setText(text, 0); } } } } } else if(paragraphOrTable instanceof XWPFTable) { // 如果是表格,则遍历其中的单元格并替换其中的变量 XWPFTable table = (XWPFTable) paragraphOrTable; for(XWPFTableRow row : table.getRows()) { for(XWPFTableCell cell : row.getTableCells()) { for(XWPFParagraph paragraph : cell.getParagraphs()) { for(XWPFRun run : paragraph.getRuns()) { String text = run.getText(0); if(text != null) { for(Map.Entry<String, String> entry : variables.entrySet()) { if(text.contains(entry.getKey())) { text = text.replace(entry.getKey(), entry.getValue()); run.setText(text, 0); } } } } } } } } } // 将修改后的文档保存为字节数组 ByteArrayOutputStream out = new ByteArrayOutputStream(); Docx4J.save(wordMLPackage, out); return out.toByteArray(); } private byte[] convertToPdf(byte[] docxBytes) throws Exception { // 加载DOCX文件 ByteArrayInputStream in = new ByteArrayInputStream(docxBytes); WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in); // 设置字体映射 Mapper fontMapper = new IdentityPlusMapper(); wordMLPackage.setFontMapper(fontMapper); // 设置页面大小和边距 PageSizePaper pageSizePaper = new PageSizePaper(); pageSizePaper.setCode("A4"); wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setPageSize(pageSizePaper); wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginTop(1440); wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginBottom(1440); wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginLeft(1440); wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginRight(1440); // 获取文档中的所有表格 java.util.List<Object> tables = wordMLPackage.getMainDocumentPart().getContent(); for (Object obj : tables) { if (obj instanceof javax.xml.bind.JAXBElement && ((javax.xml.bind.JAXBElement<?>) obj).getDeclaredType().getName().equals("org.docx4j.wml.Tbl")) { javax.xml.bind.JAXBElement<org.docx4j.wml.Tbl> element = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tbl>) obj; org.docx4j.wml.Tbl table = element.getValue(); // 设置表格边框 CTTbl ctTbl = table.getCTTbl(); CTTblPr tblPr = ctTbl.getTblPr(); if (tblPr == null) { tblPr = new CTTblPr(); ctTbl.setTblPr(tblPr); } CTTblBorders borders = tblPr.getTblBorders(); if (borders == null) { borders = new CTTblBorders(); tblPr.setTblBorders(borders); } CTBorder border = new CTBorder(); border.setColor("#000000"); border.setSz(new BigInteger("2")); CTBorderPr borderPr = new CTBorderPr(); borderPr.setTop(border); borderPr.setBottom(border); borderPr.setLeft(border); borderPr.setRight(border); borders.setTop(borderPr); borders.setBottom(borderPr); borders.setLeft(borderPr); borders.setRight(borderPr); // 设置表格宽度 CTTblGrid tblGrid = ctTbl.getTblGrid(); if (tblGrid == null) { tblGrid = new CTTblGrid(); ctTbl.setTblGrid(tblGrid); } for (int i = 0; i < table.getContent().size(); i++) { Object row = table.getContent().get(i); if (row instanceof javax.xml.bind.JAXBElement && ((javax.xml.bind.JAXBElement<?>) row).getDeclaredType().getName().equals("org.docx4j.wml.Tr")) { javax.xml.bind.JAXBElement<org.docx4j.wml.Tr> rowElement = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tr>) row; org.docx4j.wml.Tr tr = rowElement.getValue(); for (int j = 0; j < tr.getContent().size(); j++) { Object cell = tr.getContent().get(j); if (cell instanceof javax.xml.bind.JAXBElement && ((javax.xml.bind.JAXBElement<?>) cell).getDeclaredType().getName().equals("org.docx4j.wml.Tc")) { javax.xml.bind.JAXBElement<org.docx4j.wml.Tc> cellElement = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tc>) cell; org.docx4j.wml.Tc tc = cellElement.getValue(); CTTblWidth tblWidth = new CTTblWidth(); tblWidth.setType("dxa"); tblWidth.setW(BigInteger.valueOf(1000)); tc.getTcPr().setTcW(tblWidth); } } } } } } // 将文档转换为PDF ConversionOptions conversionOptions = new ConversionOptions(); conversionOptions.setQuality(PdfConversionQualityEnum.PDF_A_1_B); OutputStream out = new ByteArrayOutputStream(); PdfConversion converter = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage); converter.output(out, conversionOptions); return ((ByteArrayOutputStream) out).toByteArray(); } } ``` 在上述代码中,我们首先通过`replaceVariables()`方法将Word模板中的变量替换为实际值,然后通过`convertToPdf()`方法将DOCX文件转换为PDF。最后,我们将PDF文件写入响应体并设置响应头,使得浏览器可以下载该文件。注意,这里我们使用了`docx4j`和`poi`两个开源库来处理Word和PDF文件。

相关推荐

最新推荐

recommend-type

java生成pdf(利用dom4j、freemarker生成固定模板格式的pdf文件)

docx4j,生成docx、pptx、xlsx文档,支持转换为PDF格式。 比较: iText开源协议为AGPL,而其他两个框架协议均为Apache License v2.0。需要用画笔去花模板,很繁琐! Apache PDFBox,生成、合并PDF文档; docx4j,...
recommend-type

python实现生成Word、docx文件的方法分析

主要介绍了python实现生成Word、docx文件的方法,结合实例形式分析了Python使用docx模块操作word文件与docx文件的相关实现技巧,需要的朋友可以参考下
recommend-type

使用Aspose生成word文档-模板文件.docx

本人介绍Aspose生成word文档的模板文件,详细介绍可以参照:https://blog.csdn.net/chimmhuang/article/details/104062568。 【免费下载地址:https://gitee.com/chimmhuang/Aspose-word-demo】
recommend-type

利用python程序生成word和PDF文档的方法

主要给大家介绍了利用python程序生成word和PDF文档的方法,文中给出了详细的介绍和示例代码,相信对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。
recommend-type

JAVA通过HttpURLConnection 上传和下载文件的方法

主要介绍了JAVA通过HttpURLConnection 上传和下载文件的方法,非常具有实用价值,需要的朋友可以参考下
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

用Spring boot和vue写一个登录注册界面

好的,这是一个比较常见的技术问题,我可以为您提供一些参考资料和思路。首先,您可以使用Spring Boot作为后端框架来处理用户认证和注册的逻辑,比如使用Spring Security实现用户登录认证。同时,您还需要设计相应的数据模型和数据库表结构来存储用户信息。在前端方面,您可以使用Vue.js作为框架来构建登录注册页面,使用Axios来发起API请求并和后端进行交互。当然,在实现过程中,还需要考虑一些具体细节,比如数据校验、安全性和用户体验等方面。希望这些信息能够帮助到您。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。