如果需要linux使用,可参考这篇文章https://blog.csdn.net/weixin_45559862/article/details/154842845?spm=1001.2014.3001.5501
依赖包
java
<!--word 2 pdf start-->
<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>
代码,注意,方法的返回值可自定义,不需要删除即可。
java
package org.springblade.modules.api.utils;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;
import org.springblade.modules.api.entity.NaReport;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ExportWordToPdfUtil {
/**
* Word转PDF(根据操作系统自动选择转换方式)
*
* @param filePath 源文件路径
* @param outFilePath 输出文件路径
* @return NaReport对象,包含文件信息
*/
public static NaReport wordToPdf(String filePath, String outFilePath) {
NaReport naReport = new NaReport();
File wordFile = new File(filePath);
File pdfFile = new File(outFilePath);
// 确保输出目录存在
File parentDir = pdfFile.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
// 如果输出文件已存在则删除
if (pdfFile.exists()) {
if (!pdfFile.delete()) {
log.warn("无法删除已存在的文件: {}", outFilePath);
}
}
// 获取当前系统名称
String osName = System.getProperty("os.name").toLowerCase();
boolean success = false;
// 根据系统选择执行方法
if (osName.contains("win")) {
success = winWordToPdf(pdfFile, wordFile);
} else if (osName.contains("nux") || osName.contains("nix")) {
success = linuxWordToPdf(pdfFile, wordFile);
} else {
log.error("不支持的操作系统: {}", osName);
return null;
}
if (success && pdfFile.exists()) {
// 设置NaReport对象属性
naReport.setSize(smartConvert(pdfFile.length()));
naReport.setUrl(pdfFile.getAbsolutePath());
naReport.setFileType(getFileExtension(pdfFile));
log.info("文件转换成功: {}", outFilePath);
return naReport;
} else {
// 转换失败时删除可能生成的不完整文件
if (pdfFile.exists()) {
pdfFile.delete();
}
log.error("文件转换失败: {}", filePath);
return null;
}
}
/**
* windows系统word转pdf
* @param pdfFile 转换后的pdf文件
* @param wordFile word源文件
* @return 是否转换成功
*/
private static boolean winWordToPdf(File pdfFile, File wordFile) {
IConverter converter = null;
try {
converter = LocalConverter.builder()
.baseFolder(new File(pdfFile.getParent()))
.build();
Future<Boolean> conversion = converter.convert(new FileInputStream(wordFile))
.as(DocumentType.DOCX)
.to(new FileOutputStream(pdfFile))
.as(DocumentType.PDF)
.schedule();
return conversion.get(2, TimeUnit.MINUTES);
} catch (Exception e) {
log.error("Windows环境Word转PDF失败", e);
return false;
} finally {
if (converter != null) {
converter.shutDown();
}
}
}
/**
* linux系统word转pdf
* 使用LibreOffice转换。系统需安装LibreOffice
* @param pdfFile 转换后的pdf文件
* @param wordFile word源文件
* @return 是否转换成功
*/
private static boolean linuxWordToPdf(File pdfFile, File wordFile) {
// 获取word文件的绝对路径
String sourcePath = wordFile.getAbsolutePath();
// 获取pdf文件存放文件夹的绝对路径
String outDir = pdfFile.getParent();
// 构建LibreOffice的命令行工具命令
String command = String.format("libreoffice --invisible --convert-to pdf --outdir %s %s",
outDir, sourcePath);
log.info("执行转换命令: {}", command);
// 执行转换命令
boolean cmdSuccess = executeLinuxCmd(command);
if (cmdSuccess) {
// 检查是否生成对应的PDF文件(LibreOffice生成的文件名基于源文件名)
String generatedPdfName = wordFile.getName().replaceAll("\\.(doc|docx)$", ".pdf");
File generatedPdf = new File(outDir, generatedPdfName);
if (generatedPdf.exists()) {
// 如果生成的文件名与目标文件名不同,需要重命名
if (!generatedPdf.getName().equals(pdfFile.getName())) {
return generatedPdf.renameTo(pdfFile);
}
return true;
}
}
return false;
}
/**
* 执行命令行
* @param cmd 命令行
* @return 是否执行成功
*/
private static boolean executeLinuxCmd(String cmd) {
try {
Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd});
int exitCode = process.waitFor();
return exitCode == 0;
} catch (InterruptedException e) {
log.error("执行Linux命令被中断: ", e);
Thread.currentThread().interrupt();
return false;
} catch (IOException e) {
log.error("执行Linux命令IO异常: ", e);
return false;
}
}
/**
* 智能转换文件大小(自动选择KB或MB)
* @param bytes 文件大小(字节)
* @return 格式化后的文件大小字符串
*/
private static String smartConvert(long bytes) {
if (bytes < 1024 * 1024) { // 小于1MB
return toKB(bytes);
} else {
return toMB(bytes);
}
}
/**
* 转换为KB(保留两位小数)
* @param bytes 文件大小(字节)
* @return KB大小的字符串表示
*/
private static String toKB(long bytes) {
double kb = bytes / 1024.0;
return String.format("%.2f KB", kb);
}
/**
* 转换为MB(保留两位小数)
* @param bytes 文件大小(字节)
* @return MB大小的字符串表示
*/
private static String toMB(long bytes) {
double mb = bytes / (1024.0 * 1024.0);
return String.format("%.2f MB", mb);
}
/**
* 获取文件后缀
* @param file 文件对象
* @return 文件扩展名(小写)
*/
private static String getFileExtension(File file) {
String fileName = file.getName();
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex == -1 || dotIndex == 0 || dotIndex == fileName.length() - 1) {
return "";
}
return fileName.substring(dotIndex + 1).toLowerCase();
}
public static void main(String[] args) {
// 测试代码
String filePath = "F:\\machine\\naReport\\20251022\\1761124217178naReport.docx";
String outFilePath = "F:/machine/naReport/20251022/1761124217178naReport-转换.pdf";
NaReport result = wordToPdf(filePath, outFilePath);
if (result != null) {
System.out.println("转换成功:");
System.out.println("文件大小: " + result.getSize());
System.out.println("文件路径: " + result.getUrl());
System.out.println("文件类型: " + result.getFileType());
} else {
System.out.println("转换失败");
}
}
}