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  運行結果

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章