程式扎記: [ Java 套件 ] PDFBox - Extract text from PDF file

標籤

2014年4月2日 星期三

[ Java 套件 ] PDFBox - Extract text from PDF file

Preface: 
The Apache PDFBox™ library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command line utilities. Apache PDFBox is published under the Apache License v2.0. 這邊要來看如何利用這個套件, 將 PDF 中的文字內容給輸出. 

在準備工作當然要先去下載該套件, 這邊使用的是 pdfbox-app-1.8.4.jar (pre-built PDFBox standalone binary), 或者你可以去官方的 下載網頁 看看有沒有新版的 Release. 

Extracting text from a PDF file: 
在開始看範例代碼前, 我們先手動建立了一個測試用的 PDF 檔案: 
- test.pdf 
 

要從 PDF 檔案取出文字內容, 會使用到 PDFTextStripper class 中的方法: 
String getText(PDDocument doc) : This will return the text of a document. Remember it returns a 'String'
void writeText(PDDocument doc, Writer outputStream) : This will take a PDDocument and write the text of that document to the print writer.
getPageSeparator(): This will get the page separator.
getPageStart(): Returns the string which will be used at the beginning of a page.

除此之外, 你也可以設定要進行處理的頁數: 
public void setStartPage(int startPageValue): Where startPageValue is the starting page. The first page of the PDF is 1, second page is 2 and so on.
public void setEndPage(int endPageValue): Where endPageValue is the last page that you want to extract. The first page of the PDF is 1 and so on.

接著底下是範例代碼: 
  1. PDDocument pd;  
  2. BufferedWriter wr;  
  3. try {  
  4.     File input = new File("test.pdf"); // The PDF file from where  
  5.                                                 // you would like to  
  6.                                                 // extract  
  7.     File output = new File("test.txt"); // The text file where  
  8.                                                     // you are going to  
  9.                                                     // store the  
  10.                                                     // extracted data  
  11.     pd = PDDocument.load(input);  
  12.     System.out.println(pd.getNumberOfPages());  
  13.     System.out.println(pd.isEncrypted());             
  14.     PDFTextStripper stripper = new PDFTextStripper();  
  15.     //stripper.setStartPage(3); // Start extracting from page 3  
  16.     //stripper.setEndPage(5); // Extract till page 5  
  17.     wr = new BufferedWriter(new OutputStreamWriter(  
  18.             new FileOutputStream(output)));  
  19.     stripper.writeText(pd, wr);  
  20.     if (pd != null) {  
  21.         pd.close();  
  22.     }  
  23.     // I use close() to flush the stream.  
  24.     wr.close();  
  25. catch (Exception e) {  
  26.     e.printStackTrace();  
  27. }  
底下是輸出 test.txt 的內容: 
 

因為是 "文字內容", 所以圖片與連結並沒有辦法在文字檔中顯示. 如果要從 PDF 中取出圖片的話可以參考下面代碼: (pd 變數為 PDDocument 物件
  1. System.out.printf("\t[Info] Extract image(s)...\n");              
  2. List pages = pd.getDocumentCatalog().getAllPages();  
  3. Iterator iter = pages.iterator();             
  4.    while (iter.hasNext()) {  
  5.        PDPage page = (PDPage) iter.next();  
  6.        PDResources resources = page.getResources();  
  7.        Map pdxMap = resources.getXObjects();  
  8.        if (pdxMap != null) {   
  9.            Iterator> pdxMapIter = pdxMap.entrySet().iterator();  
  10.            while(pdxMapIter.hasNext())  
  11.            {  
  12.             Entry e = pdxMapIter.next();  
  13.             if((Object)(e.getValue()) instanceof PDXObjectImage)  
  14.             {  
  15.                 PDXObjectImage imageObj = (PDXObjectImage)e.getValue();  
  16.                 String fn = String.format("%s.jpeg", e.getKey());  
  17.                 System.out.printf("\t\tOutput %s\n", fn);  
  18.                 imageObj.write2file(new File(fn));  
  19.             }  
  20.            }                                      
  21.        }  
  22.    }  
  23.      
  24.    if (pd != null) {  
  25.     pd.close();  
  26. }  
如果要從 PDF 從取出超連結, 則可以參考下面代碼: (page 為 PDPage 物件.
  1. List l = page.getAnnotations();  
  2. for(PDAnnotation pdan:l)  
  3. {  
  4.     if(pdan instanceof PDAnnotationLink)  
  5.     {  
  6.         PDAnnotationLink link = (PDAnnotationLink)pdan;  
  7.         PDActionURI pdl= (PDActionURI)link.getAction();  
  8.         System.out.println("\t\tPDF Link: "+pdl.getURI());  
  9.         wr.append(String.format("Link: %s\n", pdl.getURI()));  
  10.     }  
  11. }  

Supplement: 
Basic PDFBox Tutorial 
PDFBox API 
Stackoverflow: extract images from pdf using pdfbox 
PDFBox extract link information

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!