市场上主流的 WORD 转 PDF 工具有两个:OpenOffice 和 Microsoft Office 转
换插件,可以通过部署这两个工具实现 WORD 转 PDF 功能。
1:
Microsoft 提 供 了 一 个 转 换 插 件 实 现 Office 转 PDF 功 能 , 即
SaveAsPDFandXPS。此插件是一个 com 组件,对于 C++、C#等语言可以直接使
用,如果是 JAVA 语言,需要通过 jacob 来调用 com 组件。
SaveAsPDFandXPS 插件要求必须有一台 Windows 服务器作为转换服务器安
装部署 Microsoft Office2007 以上的版本,然后再安装 SaveAsPDFandXPS 插件。
最后调用 com 组件实现转换。
官网地址:https://msdn.microsoft.com/en-us/library/dd301166(v=nav.90).aspx
2.
OpenOffice 是个开源的办公套件,提供了与 MS Word,Excel,PowerPoint 等
对应的多个软件,它支持包括 MS Office 2007 在内的多种格式,并且能够将其导
出为 PDF 文件。
这个方案是在 linux 服务器上安装 openOffice 然后通过 openOffice 命令来转换
pdf。
官方网址:http://www.openoffice.org/
在ubuntu下:
- tar -xvzf Apache_OpenOffice_4.1.3_Linux_x86-64_install-deb_zh-CN.tar.gz
- cd zh-CN/DEBS/
- sudo dpkg -i *.deb
- cd desktop-integration/
- sudo dpkg -i openoffice4.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端口的服务)
package openofficeTest; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.ConnectException; import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry; import com.artofsolving.jodconverter.DocumentConverter; import com.artofsolving.jodconverter.DocumentFormat; import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter; public class Word2Pdf { public static int PORT = 8100; public static void main(String[] args){ String path1 = "/tmp/1.doc"; String path2 = "/tmp/2.pdf"; try { wordToPdf(path1, path2); } catch (Exception e) { e.printStackTrace(); } } public static void wordToPdf(String path1, String path2) throws Exception { File file1 = new File(path1); File file2 = new File(path2); // 获得文件格式 DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry(); DocumentFormat pdfFormat = formatReg.getFormatByFileExtension("pdf"); DocumentFormat docFormat = formatReg.getFormatByFileExtension("doc"); // stream 流的形式 InputStream inputStream = new FileInputStream(file1); OutputStream outputStream = new FileOutputStream(file2); /** * */ OpenOfficeConnection connection = new SocketOpenOfficeConnection(PORT); System.out.println(connection); try { connection.connect(); DocumentConverter converter = new OpenOfficeDocumentConverter(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
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco; color: #4f76cb }
span.s1 { text-decoration: underline }
span.s2 { color: #9293af }
span.Apple-tab-span { white-space: pre }
安装命令:
yum install libreoffice -y
yum install libreoffice-headless -y
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco; color: #4f76cb }
span.s1 { text-decoration: underline }
span.s2 { color: #9293af }
转换命令: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) throws Exception{ File tempDir = null; try{ tempDir = Files.createTempDir(); String canonicalPath = tempDir.getCanonicalPath(); File file = new File(canonicalPath + "/" + sourceFileName); OutputStream os = new FileOutputStream(file); BufferedOutputStream bufferedOutput = new BufferedOutputStream(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<String> output = new ArrayList<String>(); BufferedReader br = new BufferedReader(new InputStreamReader(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(new FileInputStream(file2)); } } return null; }finally{ if(tempDir != null) FileUtils.deleteDirectory(tempDir); } }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco; color: #4f76cb }
span.s1 { text-decoration: underline }
span.s2 { color: #9293af }