<!-- 导出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 到 PDF
if (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 到 PDF
if (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文件打包下载。代码展示了完整的文档处理流程,包括文件创建、格式转换、压缩打包和下载清理等操作,同时提供了异常处理和资源清理机制。该方案适用于需要批量生成和导出报告文档的业务场景。