7.2 使用xpdf來處理中文PDF文件
7.2 使用xpdf來處理中文PDF文件
PDFBox看起來非常的方便,它的API功能強大。甚至能和Lucene進行無縫的結合。但是它有一個致命的弱點,就是它不支援中文。要提取中文的文字,可以採用另一個非常出色的工具xpdf。
7.2.1 xpdf的下載
讀者可以到http://www.foolabs.com/xpdf/download.html下載最新版本的xpdf。如圖7-7所示。
圖7-7 xpdf的下載頁面
本書採用的是xpdf-3.01pl2-win32.zip。另外,還需要下載一箇中文包xpdf-chinese-simplified.tar.gz。
7.2.2 配置
將xpdf-3.01pl2-win32.zip解壓到c:/xpdftest目錄下,然後將xpdf-chinese-simplified.tar.gz解壓倒c:/xpdftest/xpdf/目錄下,解壓後的目錄結構如圖7-8所示。
圖7-8 Xpdf解壓後的目錄
開啟目錄下的xpdfrc檔案,編輯檔案內容,如下程式碼所示。
程式碼7.3
cidToUnicode Adobe-GB1 c:/xpdftest/xpdf/xpdf-chinese-simplified/Adobe-GB1.cidToUnicode
unicodeMap ISO-2022-CN c:/xpdftest/xpdf/xpdf-chinese-simplified/ISO-2022-CN.unicodeMap
unicodeMap EUC-CN c:/xpdftest/xpdf/xpdf-chinese-simplified/EUC-CN.unicodeMap
unicodeMap GBK c:/xpdftest/xpdf/xpdf-chinese-simplified/GBK.unicodeMap
cMapDir Adobe-GB1 c:/xpdftest/xpdf/xpdf-chinese-simplified/CMap
toUnicodeDir c:/xpdftest/xpdf/xpdf-chinese-simplified/CMap
fontDir C:/WINDOWS/Fonts
displayCIDFontTT Adobe-GB1 C:/WINDOWS/Fonts/simhei.ttf
textEOL CR+LF
檔案的路徑讀者可以根據自己的環境改,如在windows 2000下,fontDir所在的位置是C:/WINNT/Fonts,displayCIDFontTT Adobe-GB1的位置是在C:/WINNT/Fonts/simhei.ttf。
7.2.3 提取中文
在工程中新建一個ch7.xpdf包,並建立一個Pdf2Text類。該類採用Runtime傳入引數,呼叫pdftotext.exe來進行文字的提取。其具體實現程式碼如下。
程式碼7.4
public class Pdf2Text {
// PDF檔名
private File pdffile;
// 轉換器的存放位置,預設在c:/xpdf下面
private String CONVERTOR_STORED_PATH = "c://xpdf";
// 轉換器的名稱,預設為pdftotext
private String CONVERTOR_NAME = "pdftotext";
// 建構函式,引數為pdf檔案的路徑
public Pdf2Text(String pdffile) throws IOException {
this(new File(pdffile));
}
// 建構函式,引數為pdf檔案的對像
public Pdf2Text(File pdffile) throws IOException {
this.pdffile = pdffile;
}
// 將pdf轉為文字文件
public void toTextFile() throws IOException {
toTextFile(pdffile, true);
}
// 將pdf轉為文字文件,引數為目標檔案的路徑,預設使用PDF檔案中的佈局
public void toTextFile(String targetfile) throws IOException {
toTextFile(new File(targetfile), true);
}
// 將pdf轉為文字文件,引數1為目標檔案的路徑,
// 引數2為true則表示使用PDF檔案中的佈局
public void toTextFile(String targetfile, boolean isLayout)
throws IOException {
toTextFile(new File(targetfile), isLayout);
}
// 將pdf轉為文字文件,引數為目標檔案
public void toTextFile(File targetfile) throws IOException {
toTextFile(targetfile, true);
}
// 將pdf轉為文字文件,引數1為目標檔案,
// 引數2為true則表示使用PDF檔案中的佈局
public void toTextFile(File targetfile, boolean isLayout)
throws IOException {
String[] cmd = getCmd(targetfile, isLayout);
Process p = Runtime.getRuntime().exec(cmd);
}
// 獲取PDF轉換器的路徑
public String getCONVERTOR_STORED_PATH() {
return CONVERTOR_STORED_PATH;
}
// 設定PDF轉換器的路徑
public void setCONVERTOR_STORED_PATH(String path) {
if (!path.trim().endsWith("//"))
path = path.trim() + "//";
this.CONVERTOR_STORED_PATH = path;
}
// 解析命令列引數
private String[] getCmd(File targetfile, boolean isLayout) {
// 命令字元
String command = CONVERTOR_STORED_PATH + CONVERTOR_NAME;
// PDF檔案的絕對路徑
String source_absolutePath = pdffile.getAbsolutePath();
// 輸出文字檔案的絕對路徑
String target_absolutePath = targetfile.getAbsolutePath();
// 保持原來的layout
String layout = "-layout";
// 設定編碼方式
String encoding = "-enc";
String character = "GBK";
// 設定不列印任何訊息和錯誤
String mistake = "-q";
// 頁面之間不加入分頁
String nopagebrk = "-nopgbrk";
// 如果isLayout為false,則設定不保持原來的layout
if (!isLayout)
layout = "";
return new String[] { command, layout, encoding, character, mistake,
nopagebrk, source_absolutePath, target_absolutePath };
}
}
該類對外提供一個toTextFile()方 法。該方法接收2個引數:targetfile為目標PDF檔案,isLayout表示是否採用原始的PDF檔案中的layout佈局。類中的 getCmd()方法負責解析傳進來的引數,並生成一個String陣列。該String陣列表示一個作業系統中的命令,其中,各項分別代表命令後所跟的 引數。在獲得到該陣列後,再呼叫Runtime.getRuntime().exec(String[])函式來執行命令。
注意:在getCmd()方法中設定編碼方式的 時候,用到的是GBK。這並不是對所有的檔案都適用,因為中文的編碼方式不只一種,讀者可以根據PDF的編碼型別選擇不同的encoding方式。所有簡 體中文的編碼方式都定義在檔案xpdfrc中的unicodeMap中,現在支援3種編碼方式,分別是ISO-2022-CN,EUC-CN,GBK,如 圖7-9所示。
圖7-9 xpdfrc檔案的內容
7.2.4 執行效果
下面通過一個函式來測試Pdf2Text類,在ch7.xpdf包中新建一個Pdf2TextTest類,包含一個main函式,其程式碼如下。
程式碼7.5
public class Pdf2TextTest {
public static void main(String[] args) {
try {
// 引數輸入PDF檔案的存放位置
Pdf2Text p2t = new Pdf2Text("c://test.pdf");
// 設定轉換器的位置
p2t.setCONVERTOR_STORED_PATH("c://xpdftest//xpdf");
// 設定文字檔案存放位置
p2t.toTextFile("c://test.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
}
用於轉換的PDF檔案如圖7-10所示。
圖7-10 用於轉換的中文PDF檔案
程式碼7.5執行之後,結果如圖7-11所示。
圖7-11 執行結果