调研
可供选择的方案并不多,解决思路可以分成两类。一类是直接使用工具将pdf转成word,另一类是先用工具将pdf中的内容提取出来,再使用其他工具将内容创建到新的word中。目前,着重尝试了第一类方案。
第一类方案中最流行的方法是使用pdfbox工具包,另一种方法是使用COM技术,利用java调用windows平台的COM组件完成转换。第一种方法完全使用java库,没有平台限制,第二种方法则依赖于windows平台,Adobe的Acrobat软件在pdf转word中功能良好,Jacob可以实现java代码和COM组件之间的互操作。
分别尝试了上述两种方法,发现第二种方法转换效果更好一些。
原pdf文件
使用PDFBOX的转换结果
Acrobat的转换结果
从图中可以看出使用pdfbox转换的结果原来的格式已经没有了,并且表格也没有解析出来。但是使用Acrobat转换的结果能较完整的保留原来的格式。下面的解决方案主要介绍使用Acrobat实现的方法。
代码
import java.io.File;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Pdf2Word {
public static void main(String[] args) {
File inPath = new File("./test.pdf");
File outPath = new File("./test.docx");
//pdfActiveX PDDoc对象 主要建立PDF对象
ActiveXComponent app = new ActiveXComponent("AcroExch.PDDoc");
//PDF控制对象
Dispatch pdfObject = app.getObject();
long start = System.currentTimeMillis();
//打开PDF文件,建立PDF操作的开始
Dispatch.call(pdfObject, "Open", new Variant(inPath.getAbsolutePath()));
Variant jsObj = Dispatch.call(pdfObject, "GetJSObject");
Dispatch.call(jsObj.getDispatch(), "SaveAs", outPath.getPath(), "com.adobe.acrobat.docx");
app.invoke("Close");
long end = System.currentTimeMillis();
System.out.println((end-start)/1000);
System.out.println("Wao-haha");
}
}
代码比较简短,第14行中“AcroExch.PDDoc”是Acrobat安装后注册的COM组件;组件方法参考:https://help.adobe.com/en_US/acrobat/acrobat_dc_sdk/2015/HTMLHelp/#t=Acro12_MasterBook%2FIAC_API_OLE_Objects%2FOLE_Automation2.htm。
使用方法
环境配置
Jacob
从https://sourceforge.net网站查找并下载Jacob。下载的ZIP包的结构如图所示。 Jacob.jar引入到项目中;dll文件有两个根据自己电脑的平台选择合适的文件放在 %JAVA_HOME%\jre\bin 或 %JAVA_HOME%\bin 目录下。
Acrobat
下载后直接安装
首先要确保在windows平台上。调用时可以对代码进行再组织,封装成一个方法。需要注意的是转换过程比较耗时,如果转换一个大文件或者短时间内转换多个文件可以考虑多线程。
性能
电脑配置:Intel i5-7300HQ,8G内存,64位Win10系统
转换一个3页的pdf论文,用时4s。
转换一个554页的pdf格式的电子书,用时80s。