LibreOffice 是开源免费的office ,下载地址: https://www.libreoffice.org/download/download-libreoffice/
实现转换的核心命令行是:
soffice --headless --convert-to pdf:writer_pdf_Export --outdir ./out test.docx
这里简单的用java runtime 包了一下命令,实现的转换:
代码如下:
package com.trydone.samples;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* 简单使用LibreOffice 实现文档转PDF
*
* @author pinke
* @since 2024-02-21
*/
public class Office2Pdf {
//不同系统要下载相应安装程序,并配置好地址
//下载地址: https://www.libreoffice.org/download/download-libreoffice/
//以下是MacOS上安装好的地址,其它系统请自行修改
private static final String OFFICE_BIN = "/Applications/LibreOffice.app/Contents/MacOS/soffice";
//支持转换的类型
private static final String[] ALLOW_EXTENDS = {".docx", ".doc", ".xls", ".xlsx", ".ppt", ".pptx", ".txt"};
public static void main(String[] args) {
long useTime = System.currentTimeMillis();
try {
office2pdf("/Users/pinke/Downloads/test.docx",
"/Users/pinke/Downloads/out/a.pdf");
office2pdf("/Users/pinke/Downloads/演示文稿1.pptx",
"/Users/pinke/Downloads/out/b.pdf");
office2pdf("/Users/pinke/Downloads/工作簿1.xlsx",
"/Users/pinke/Downloads/out/c.pdf");
} catch (Throwable e) {
throw new RuntimeException(e);
} finally {
System.out.println("处理用时:" + (System.currentTimeMillis() - useTime));
}
}
public static void office2pdf(String docxPathAndName, String pdfPathAndName) throws IOException {
File srcFile = new File(docxPathAndName);
if (!srcFile.exists()) {
throw new IOException("文件不存在!" + srcFile.getAbsolutePath());
}
File destFile = new File(pdfPathAndName);
if (destFile.exists() && !destFile.delete()) {
throw new IOException("文件已经存在,无法覆盖!" + destFile.getAbsolutePath());
}
if (!srcFile.canRead()) {
throw new IOException("文件不可用!" + srcFile.getAbsolutePath());
}
String convertExt = null;
String lowFileName = srcFile.getName().toLowerCase();
for (String ext : ALLOW_EXTENDS) {
if (lowFileName.endsWith(ext)) {
convertExt = ext;
}
}
if (convertExt == null) {
throw new IOException("不支持的文件扩展名!");
}
//生成个随机文件名
String name = UUID.randomUUID().toString();
File tmpSrcFile = File.createTempFile("office2pdf-" + name, convertExt);
File tmpDstFile = null;
try {
FileUtils.copyFile(new File(docxPathAndName), tmpSrcFile);
String srcFileFullPath = tmpSrcFile.getAbsolutePath();
//核心是这些转换参数
Process proc = Runtime.getRuntime().exec(new String[]{
OFFICE_BIN,
"--headless",
"--convert-to",
"pdf:writer_pdf_Export",
"--outdir",
tmpSrcFile.getParentFile().getAbsolutePath(),
srcFileFullPath
});
proc.waitFor();
if (proc.exitValue() == 0) {
String distPdfFile = srcFileFullPath.substring(0, srcFileFullPath.length() - convertExt.length()) + ".pdf";
tmpDstFile = new File(distPdfFile);
int ct = 0;
while (!tmpDstFile.exists() && ct++ < 10) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
//
}
}
if (!tmpDstFile.exists()) {
throw new IOException("处理异常,没有正常生成,请稍后重试.");
}
FileUtils.moveFile(tmpDstFile, destFile);
tmpDstFile = null;//移走了,就不要清理
} else {
throw new IOException("处理异常,请检查office是否安装正常.");
}
} catch (IOException e) {
throw e;
} catch (Throwable e) {
throw new IOException(e);
} finally {
//清理临时文件
try {
tmpSrcFile.delete();
} catch (Throwable e) {
//
}
try {
if (tmpDstFile != null) tmpDstFile.delete();
} catch (Throwable e) {
//
}
}
}
}