市场上主流的 WORD 转 PDF 工具有两个:OpenOffice 和 Microsoft Office 转
换插件,可以通过部署这两个工具实现 WORD 转 PDF 功能。
1:
Microsoft 提 供 了 一 个 转 换 插 件 实 现 Office 转 PDF 功 能 , 即
SaveAsPDFandXPS。此插件是一个 com 组件,对于 C++、C#等语言可以直接使
用,如果是 JAVA 语言,需要通过 jacob 来调用 com 组件。
SaveAsPDFandXPS 插件要求必须有一台 Windows 服务器作为转换服务器安
装部署 Microsoft Office 以上的版本,然后再安装 SaveAsPDFandXPS 插件。
最后调用 com 组件实现转换。
官网地址:/en-us/library/dd301166(v=nav.90).aspx
2.
OpenOffice 是个开源的办公套件,提供了与 MS Word,Excel,PowerPoint 等
对应的多个软件,它支持包括 MS Office 在内的多种格式,并且能够将其导
出为 PDF 文件。
这个方案是在 linux 服务器上安装 openOffice 然后通过 openOffice 命令来转换
pdf。
官方网址:/
在ubuntu下:
tar-xvzfApache_OpenOffice_4.1.3_Linux_x86-64_install-deb_zh-CN.tar.gz
cdzh-CN/DEBS/
sudodpkg-i*.deb
cddesktop-integration/
sudodpkg-iopenoffice4.1-debian-menus_4.1.3-9783_all.deb
soffice--headless--accept="socket,host=127.0.0.1,port=8100;urp;"--nofirststartwizard&
启动服务,# netstat -an|more,可查看是否启动成功(是否有8100端口的服务)
packageopenofficeTest;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;.ConnectException;importcom.artofsolving.jodconverter.DefaultDocumentFormatRegistry;importcom.artofsolving.jodconverter.DocumentConverter;importcom.artofsolving.jodconverter.DocumentFormat;importcom.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;importcom.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;importcom.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;public classWord2Pdf {public static int PORT = 8100;public static voidmain(String[] args){
String path1= "/tmp/1.doc";
String path2= "/tmp/2.pdf";try{
wordToPdf(path1, path2);
}catch(Exception e) {
e.printStackTrace();
}
}public static voidwordToPdf(String path1, String path2)throwsException {
File file1= newFile(path1);
File file2= newFile(path2);//获得文件格式
DefaultDocumentFormatRegistry formatReg = newDefaultDocumentFormatRegistry();
DocumentFormat pdfFormat= formatReg.getFormatByFileExtension("pdf");
DocumentFormat docFormat= formatReg.getFormatByFileExtension("doc");//stream 流的形式
InputStream inputStream = newFileInputStream(file1);
OutputStream outputStream= newFileOutputStream(file2);/****/OpenOfficeConnection connection= new SocketOpenOfficeConnection(PORT);
System.out.println(connection);try{
connection.connect();
DocumentConverter converter= newOpenOfficeDocumentConverter(connection);converter.convert(inputStream, docFormat, outputStream, pdfFormat);
}catch(ConnectException e) {
e.printStackTrace();
}finally{if (connection != null) {
connection.disconnect();
connection= null;
}
}
}
}
但是,经过测试,openoffice转换的速度明显很慢,主要是在获取OpenOfficeConnection这块,我目前还没有找到能明显提升速度的方法,下面还有第三种基于libreoffice做转换的方式。
前提条件:要安装libreoffice, libreoffice-headless
安装命令:
yum install libreoffice -y
yum install libreoffice-headless -y
转换命令:libreoffice --headless --convert-to pdf:writer_pdf_Export --outdir /tmp//tmp/test.doc
其中/tmp/test.doc为测试用的doc文件,生成的pdf文件会在/tmp/下,名称会默认和doc的名字一样。
下面是项目中以doc文件流输入,返回pdf文件流的方法。
public static byte[] toPDF(byte[] b, String sourceFileName) throwsException{
File tempDir= null;try{
tempDir=Files.createTempDir();
String canonicalPath=tempDir.getCanonicalPath();
File file= new File(canonicalPath + "/" +sourceFileName);
OutputStream os= newFileOutputStream(file);
BufferedOutputStream bufferedOutput= newBufferedOutputStream(os);
bufferedOutput.write(b);
String command= "libreoffice";
Process proc= new ProcessBuilder(command, "--headless", "--convert-to", "pdf:writer_pdf_Export", "--outdir", canonicalPath, canonicalPath + "/" +sourceFileName)
.redirectErrorStream(true)
.start();
ArrayList output = new ArrayList();
BufferedReader br= new BufferedReader(newInputStreamReader(proc.getInputStream()));
String line= null;while ((line = br.readLine()) != null)
output.add(line);
logger.info("执行pdf转换命令的输出:" +StringUtils.join(output, System.lineSeparator()));if (0 !=proc.waitFor())throw new Exception("转换失败");
File[] files=tempDir.listFiles();for(File file2 : files) {if (file2.getPath().endsWith(".pdf")) {return IOUtils.toByteArray(newFileInputStream(file2));
}
}return null;
}finally{if(tempDir != null)
FileUtils.deleteDirectory(tempDir);
}
}