java根据word模板生成word,在根据word文件转换成pdf文件
1.引入pom文件
<!-- Apache POI for Word document generation --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>5.2.3</version> </dependency> <!-- Apache POI PDF Converter --> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.converter.docx.xwpf</artifactId> <version>2.0.6</version> </dependency>
2.Word模板使用说明
在`src/main/resources/templates/`(自定义)目录下放置Word模板文件,例如`rectification_template.docx`。
在模板中使用占位符格式:`${字段名}`,例如:
- `${safe}`
- `${quality}`
当调用接口时,系统会根据模板和数据生成新的Word文档

3.代码
@ApiOperation("预览PDF文档")
@GetMapping("/previewPdfDocument/{id}")
public void previewPdfDocument(@PathVariable Long id, HttpServletResponse response) {
try {
// 生成PDF文档文件
File pdfFile = rectificationService.generatePdfDocumentFile(id);
if (pdfFile == null) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文档生成失败");
return;
}
// 设置响应头,使浏览器直接预览而不是下载
response.setContentType("application/pdf");
response.setContentLength((int) pdfFile.length());
// 写入响应
try (FileInputStream fileInputStream = new FileInputStream(pdfFile);
ServletOutputStream outputStream = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
}
// 删除临时文件
pdfFile.delete();
} catch (Exception e) {
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文档生成或预览过程中发生错误: " + e.getMessage());
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
4.代码2
@Override
public File generatePdfDocumentFile(Long id) {
try {
// 首先生成Word文档
ByteArrayOutputStream wordOutputStream = generatePdf(id);
if (wordOutputStream == null) {
return null;
}
// 创建临时文件
File pdfFile = File.createTempFile("rectification_" + id + "_", ".pdf");
// 将Word转换为PDF并写入文件
try (ByteArrayInputStream wordInputStream = new ByteArrayInputStream(wordOutputStream.toByteArray());
FileOutputStream pdfOutputStream = new FileOutputStream(pdfFile)) {
PdfUtil.convertWordToPdfFormatted(wordInputStream, pdfOutputStream);
return pdfFile;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
5.模板数据填入
@Override public ByteArrayOutputStream generatePdf(Long id) { Intion entity = baseMapper.selectById(id);//改成自己需要的数据 if (null == entity) { return null; } //模板路径 ClassPathResource resource = new ClassPathResource("templates/rectification_template.docx"); // 准备模板数据 Map<String, Object> dataMap = new HashMap<>(); dataMap.put("safe", entity.getSafe()); try { // 获取模板路径 String templatePath = resource.getFile().getAbsolutePath(); // 生成Word文档 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); WordTemplateUtil.generateWordFromTemplate(templatePath, dataMap, outputStream); return outputStream; } catch (Exception e) { e.printStackTrace(); return null; } }
6.word工具类
import org.apache.poi.xwpf.usermodel.*; import java.io.*; import java.util.Map; import java.util.List; /** * Word模板工具类 * 根据Word模板生成带数据的Word文档 */ public class WordTemplateUtil { /** * 根据模板生成Word文档 * @param templatePath 模板文件路径 * @param params 数据参数 * @param outputStream 输出流 * @throws IOException IO异常 */ public static void generateWordFromTemplate(String templatePath, Map<String, Object> params, OutputStream outputStream) throws IOException { try (FileInputStream fis = new FileInputStream(templatePath); XWPFDocument document = new XWPFDocument(fis)) { // 替换段落中的占位符 replaceInParagraphs(document, params); // 替换表格中的占位符 replaceInTables(document, params); // 写入输出流 document.write(outputStream); } } /** * 替换段落中的占位符 * @param document Word文档 * @param params 参数映射 */ private static void replaceInParagraphs(XWPFDocument document, Map<String, Object> params) { for (XWPFParagraph paragraph : document.getParagraphs()) { for (XWPFRun run : paragraph.getRuns()) { String text = run.getText(0); if (text != null) { for (Map.Entry<String, Object> entry : params.entrySet()) { String placeholder = "${" + entry.getKey() + "}"; Object value = entry.getValue(); if (text.contains(placeholder)) { text = text.replace(placeholder, value != null ? value.toString() : ""); run.setText(text, 0); } } } } } } /** * 替换表格中的占位符 * @param document Word文档 * @param params 参数映射 */ private static void replaceInTables(XWPFDocument document, Map<String, Object> params) { for (XWPFTable table : document.getTables()) { 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, Object> entry : params.entrySet()) { String placeholder = "${" + entry.getKey() + "}"; Object value = entry.getValue(); if (text.contains(placeholder)) { text = text.replace(placeholder, value != null ? value.toString() : ""); run.setText(text, 0); } } } } } } } } } /** * 生成表格数据 * @param document Word文档 * @param bookmark 表格书签 * @param headers 表头 * @param dataList 数据列表 */ public static void generateTableData(XWPFDocument document, String bookmark, String[] headers, List<Object[]> dataList) { // 查找书签位置 // 这里简化处理,实际应用中可以通过查找书签位置来确定表格插入点 // 创建表格 XWPFTable table = document.createTable(); // 设置表头 XWPFTableRow headerRow = table.getRow(0); for (int i = 0; i < headers.length; i++) { if (i == 0) { headerRow.getCell(0).setText(headers[i]); } else { headerRow.addNewTableCell().setText(headers[i]); } } // 填充数据 for (Object[] rowData : dataList) { XWPFTableRow row = table.createRow(); for (int i = 0; i < rowData.length; i++) { row.getCell(i).setText(rowData[i] != null ? rowData[i].toString() : ""); } } } }
7.pdf 工具类
import org.apache.poi.xwpf.usermodel.XWPFDocument; import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter; import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; /** * PDF工具类 * 提供Word转PDF等功能 */ public class PdfUtil { /** * 将Word文档转换为PDF (使用Apache POI实现) * 使用org.apache.poi.xwpf.usermodel.XWPFDocument和fr.opensagres.poi.xwpf.converter.pdf实现转换 * @param wordInputStream Word文档输入流 * @param pdfOutputStream PDF文档输出流 * @throws Exception 转换异常 */ public static void convertWordToPdfFormatted(InputStream wordInputStream, OutputStream pdfOutputStream) throws Exception { try { // 使用Apache POI加载Word文档 XWPFDocument document = new XWPFDocument(wordInputStream); // 创建PDF转换选项 PdfOptions options = PdfOptions.create(); // 执行转换 PdfConverter.getInstance().convert(document, pdfOutputStream, options); } catch (IOException e) { throw new Exception("转换Word为PDF失败", e); } } }
浙公网安备 33010602011771号