Java如何导出word(根据模板生成),通过word转成pdf,放压缩包
<!-- 导出word文档所需依赖--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.0-beta</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.1.2</version></dependency><!-- 导出word文档所需依赖--><!-- word转pdf 依赖--><dependency><groupId>com.documents4j</groupId><artifactId>documents4j-local</artifactId><version>1.0.3</version></dependency><dependency><groupId>com.documents4j</groupId><artifactId>documents4j-transformer-msoffice-word</artifactId><version>1.0.3</version></dependency><!-- word转pdf 依赖-->
代码
// 导出报告 word文档 模板类型 正式节点才能导出报告@GetMapping("/exportReportWord")@ApiOperationSupport(order = 8)@ApiOperation(value = "导出报告 PDF 文档", notes = "")public void exportReportWord(@RequestParam String ids, HttpServletResponse response) throws IOException {List<CmComplaintEntity> joints = cmComplaintService.listByIds(Func.toStrList(ids));String uuid = UUID.randomUUID().toString();Path zipPath = Paths.get(pathProperties.getReport(), uuid + ".zip");File zipFile = zipPath.toFile();if (zipFile.exists()) {zipFile.delete(); // 如果文件存在则先删除旧的文件}List<File> pdfFiles = null;try {if (!zipFile.getParentFile().exists()) {Files.createDirectories(zipPath.getParent());}pdfFiles = joints.stream().map(joint -> {String fileName = joint.getWorkOrderNo();Path docxPath = Paths.get(pathProperties.getReport(), uuid, fileName + ".docx");Path pdfPath = Paths.get(pathProperties.getReport(), uuid, fileName + ".pdf");File docxFile = docxPath.toFile();File pdfFile = pdfPath.toFile();try {if (!docxFile.getParentFile().exists()) {Files.createDirectories(docxPath.getParent());}if (!docxFile.exists()) {Files.createFile(docxPath);}// 生成 Word 文档XWPFTemplate template = getXwpfTemplate(joint);try (FileOutputStream fos = new FileOutputStream(docxFile)) {template.write(fos);}// 转换 Word 到 PDFif (docxFile.exists()) {convertWordToPdf(docxFile, pdfFile);}} catch (Exception e) {e.printStackTrace();}return pdfFile;}).collect(Collectors.toList());// 压缩 PDF 文件ZipUtil.zipFile(pdfFiles, zipPath.toFile().getAbsolutePath());} catch (Exception e) {e.printStackTrace();} finally {if (pdfFiles != null) {for (File f : pdfFiles) {if (f.exists()) {f.delete();}}}Path dirPath = Paths.get(pathProperties.getReport(), uuid);if (dirPath.toFile().exists()) {dirPath.toFile().delete();}}// 下载文件InputStream inStream = null;try {if (!zipFile.exists()) {return;}inStream = new FileInputStream(zipFile);response.reset();response.setContentType("application/zip");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));response.setCharacterEncoding("UTF-8");IoUtil.copy(inStream, response.getOutputStream());} catch (Exception e) {e.printStackTrace();} finally {if (inStream != null) {try {inStream.close();} catch (IOException e) {e.printStackTrace();}}if (zipFile.exists()) {zipFile.delete(); // 压缩包也删除}}}/*** 传入 节点对象 返回生成的word文档* @param flangeJoint* @return* @throws IOException*/private XWPFTemplate getXwpfTemplate(CmComplaintEntity flangeJoint) throws IOException {Map<String, Object> map = new HashMap<>();
// List<Map<String, Object>> table = this.setListData(flangeJoints); 无内循环表格
// map.put("table", table);map.put("jointNo", "123");// 导出PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource resource = resolver.getResource("classpath:/templates/jointReport_en.docx");
// Configure config = Configure.builder().bind("table", new LoopRowTableRenderPolicy()).build();
// XWPFTemplate template = XWPFTemplate.compile(resource.getInputStream(), config).render(map);XWPFTemplate template = XWPFTemplate.compile(resource.getInputStream()).render(map);return template;}/*** 将Word文件转换为PDF文件* @param wordFile Word文件* @param pdfFile PDF文件*/public void convertWordToPdf(File wordFile, File pdfFile) {try (InputStream docxInputStream = new FileInputStream(wordFile);OutputStream outputStream = new FileOutputStream(pdfFile)) {IConverter converter = LocalConverter.builder().build();converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();System.out.println("Word转PDF成功: " + wordFile.getName());} catch (Exception e) {e.printStackTrace();System.err.println("Word转PDF失败: " + wordFile.getName() + ", 错误: " + e.getMessage());}}
如果是直接生成word的话,用下面的代码:
// 导出报告 word文档 模板类型 正式节点才能导出报告@GetMapping("/exportReportWord")@ApiOperationSupport(order = 8)@ApiOperation(value = "导出报告 PDF 文档", notes = "")public void exportReportWord(@RequestParam String ids, HttpServletResponse response) throws IOException {List<CmComplaintEntity> joints = cmComplaintService.listByIds(Func.toStrList(ids));String uuid = UUID.randomUUID().toString();Path zipPath = Paths.get(pathProperties.getReport(), uuid + ".zip");File zipFile = zipPath.toFile();if (zipFile.exists()) {zipFile.delete(); // 如果文件存在则先删除旧的文件}List<File> pdfFiles = null;try {if (!zipFile.getParentFile().exists()) {Files.createDirectories(zipPath.getParent());}pdfFiles = joints.stream().map(joint -> {String fileName = joint.getWorkOrderNo();Path docxPath = Paths.get(pathProperties.getReport(), uuid, fileName + ".docx");Path pdfPath = Paths.get(pathProperties.getReport(), uuid, fileName + ".pdf");File docxFile = docxPath.toFile();File pdfFile = pdfPath.toFile();try {if (!docxFile.getParentFile().exists()) {Files.createDirectories(docxPath.getParent());}if (!docxFile.exists()) {Files.createFile(docxPath);}// 生成 Word 文档XWPFTemplate template = getXwpfTemplate(joint);try (FileOutputStream fos = new FileOutputStream(docxFile)) {template.write(fos);}// 转换 Word 到 PDFif (docxFile.exists()) {convertWordToPdf(docxFile, pdfFile);}} catch (Exception e) {e.printStackTrace();}return pdfFile;}).collect(Collectors.toList());// 压缩 PDF 文件ZipUtil.zipFile(pdfFiles, zipPath.toFile().getAbsolutePath());} catch (Exception e) {e.printStackTrace();} finally {if (pdfFiles != null) {for (File f : pdfFiles) {if (f.exists()) {f.delete();}}}Path dirPath = Paths.get(pathProperties.getReport(), uuid);if (dirPath.toFile().exists()) {dirPath.toFile().delete();}}// 下载文件InputStream inStream = null;try {if (!zipFile.exists()) {return;}inStream = new FileInputStream(zipFile);response.reset();response.setContentType("application/zip");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));response.setCharacterEncoding("UTF-8");IoUtil.copy(inStream, response.getOutputStream());} catch (Exception e) {e.printStackTrace();} finally {if (inStream != null) {try {inStream.close();} catch (IOException e) {e.printStackTrace();}}if (zipFile.exists()) {zipFile.delete(); // 压缩包也删除}}}/*** 传入 节点对象 返回生成的word文档* @param flangeJoint* @return* @throws IOException*/private XWPFTemplate getXwpfTemplate(CmComplaintEntity flangeJoint) throws IOException {Map<String, Object> map = new HashMap<>();
// List<Map<String, Object>> table = this.setListData(flangeJoints); 无内循环表格
// map.put("table", table);map.put("jointNo", "123");// 导出PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource resource = resolver.getResource("classpath:/templates/jointReport_en.docx");
// Configure config = Configure.builder().bind("table", new LoopRowTableRenderPolicy()).build();
// XWPFTemplate template = XWPFTemplate.compile(resource.getInputStream(), config).render(map);XWPFTemplate template = XWPFTemplate.compile(resource.getInputStream()).render(map);return template;}/*** 将Word文件转换为PDF文件* @param wordFile Word文件* @param pdfFile PDF文件*/public void convertWordToPdf(File wordFile, File pdfFile) {try (InputStream docxInputStream = new FileInputStream(wordFile);OutputStream outputStream = new FileOutputStream(pdfFile)) {IConverter converter = LocalConverter.builder().build();converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();System.out.println("Word转PDF成功: " + wordFile.getName());} catch (Exception e) {e.printStackTrace();System.err.println("Word转PDF失败: " + wordFile.getName() + ", 错误: " + e.getMessage());}}
下面有一个依赖的工具类
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;import java.io.File;
import java.nio.charset.Charset;
import java.util.List;public class ZipUtil {public static void zipFile(File dir, String file) throws ZipException {// 生成的压缩文件ZipFile zipFile = new ZipFile(file);ZipParameters parameters = new ZipParameters();// 压缩方式parameters.setCompressionMethod(CompressionMethod.DEFLATE);// 压缩级别parameters.setCompressionLevel(CompressionLevel.FAST);// 要打包的文件夹File[] list = dir.listFiles();// 遍历文件夹下所有的文件、文件夹for (File f: list) {if (f.isDirectory()) {zipFile.addFile(f.getPath(), parameters);} else {zipFile.addFile(f, parameters);}}}public static void zipFile(List<File> list, String file) throws ZipException {// 生成的压缩文件ZipFile zipFile = new ZipFile(file);ZipParameters parameters = new ZipParameters();// 压缩方式parameters.setCompressionMethod(CompressionMethod.STORE);// 压缩级别parameters.setCompressionLevel(CompressionLevel.FAST);// 遍历文件夹下所有的文件、文件夹for (File f: list) {if (f.isDirectory()) {zipFile.addFile(f.getPath(), parameters);} else {zipFile.addFile(f, parameters);}}}public static void unzip(String srcFile, String destDir) throws Exception {/** 判断文件是否存在 */File file = new File(srcFile);if (file.exists()) {ZipFile zipFile = new ZipFile(srcFile);// 设置编码格式中文设置为GBK格式zipFile.setCharset(Charset.forName("GBK"));// 解压压缩包zipFile.extractAll(destDir);}}}
这个工具类依赖于
<!-- zip --><dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>2.7.0</version></dependency>
本文介绍了一个基于Java的文档处理方案,主要实现Word文档生成和PDF转换功能。系统使用poi-tl和Apache POI库生成Word文档,通过documents4j实现Word转PDF,并采用zip4j进行文件压缩。核心功能包括:1)根据模板动态生成Word文档;2)将Word批量转换为PDF;3)将多个PDF文件打包下载。代码展示了完整的文档处理流程,包括文件创建、格式转换、压缩打包和下载清理等操作,同时提供了异常处理和资源清理机制。该方案适用于需要批量生成和导出报告文档的业务场景。