PDFBox的使用——分頁提取PDF文本

來源:互聯網
上載者:User

標籤:

 

需求:用java分頁提取PDF文本。

PDFBox是一個很好的可以滿足上述需求的開源工具。

1.PDF文檔結構

要解析PDF文本,我們首先要瞭解PDF檔案的結構。

關於PDF文檔,最重要的幾點:

一,PDF文檔內容比較複雜,比如有純文字(可以提取出其中的文字,可以用PDF軟體中的“複製”功能)、圖片(無法使用PDF軟體中的“複製”功能)、表單、視頻、音頻等,總之形式比較複雜;

二,PDF檔案採用二進位流與純文字混合的編碼模式,並且沒有採用 Unicode 等標準字元編碼方式,其字元編碼採用 Adobe 公司內建的編碼錶( CMap),這使得對 PDF 的處理更加困難;

三,PDF有自己的檔案結構:檔案頭,對象集合,交叉參考資料表,結尾(準確地說,這是PDF文檔的物理結構,還有邏輯結構,詳情可以點擊查看這篇博文)。

2.PDFBox是個什麼玩意
  • 授權協議: Apache
  • 開發語言: Java
  • 作業系統: 跨平台
  • 官網:http://pdfbox.apache.org/
3.PDFBox能幹啥
  • 從PDF提取文本
  • 合并PDF文檔
  • PDF 文檔加密與解密
  • 與Lucene搜尋引擎的整合
  • 填充PDF/XFDF表單資料
  • 從文字檔建立PDF文檔
  • 從PDF頁面建立圖片
  • 列印PDF文檔
4.準備工作

再次聲明,本demo功能是提取PDF文本(目前只測試了英文可以提取,中文暫未驗證)。

1) 下載好jar包(3個):

a.fontbox-2.0.0-RC2.jar

b.pdfbox-2.0.0-RC2.jar

c.pdfbox-app-2.0.0-RC2.jar

:進官網一看便知(注意版本)。

2) myeclipse或eclipse。

5.開始編程

建立一個項目,寫入下面的源碼:

  1 package com.primeton.pdfbox;  2   3 import java.io.File;  4 import java.io.FileOutputStream;  5 import java.io.OutputStreamWriter;  6 import java.io.Writer;  7   8 import org.apache.pdfbox.pdmodel.PDDocument;  9 import org.apache.pdfbox.text.PDFTextStripper; 10  11  12 /** 13  * PDFBox解析PDF文本實現 14  * @author MrChen 15  * 16  */ 17  18 public class PDFReader { 19     /** 20       * @param args 21       */ 22      public static void main(String[] args) { 23       // TODO Auto-generated method stub 24       PDFReader pdfReader = new PDFReader(); 25       System.out.println("E:\\AndroidStudio.pdf"); 26       try { 27            // 取得E盤下的SpringGuide.pdf的內容 28            System.out.println("開始提取"); 29            File file = new File("E:\\AndroidStudio.pdf"); 30            System.out.println("檔案絕對路徑為:"+file.getAbsolutePath()); 31            pdfReader.readFdf(file); 32            System.out.println("提取結束"); 33       } catch (Exception e) { 34            e.printStackTrace(); 35       } 36      } 37       38      public void readFdf(File pdfFile) throws Exception { 39           // 是否排序 40           boolean sort = false; 41           // 輸入文字檔名稱 42           String textFileName = null; 43           // 編碼方式 44           String encoding = "UTF-8"; 45           // 開始提取頁數 46           int startPage = 1; 47           // 結束提取頁數 48           int endPage = 3; 49           // 檔案輸入資料流,產生文字檔 50           Writer output = null; 51           // 記憶體中儲存的PDF Document 52           PDDocument document = null; 53            54           File outputFile = null; 55           try { 56           57                // 從本地裝載檔案 58                //注意參數已不是以前版本中的URL.而是File。 59                 System.out.println("開始裝載檔案"+pdfFile.getName()); 60                 document = PDDocument.load(pdfFile); 61                 if (pdfFile.getName().length() > 4) { 62                     textFileName = pdfFile.getName().substring(0, pdfFile.getName().length() - 4) + ".txt"; 63                     outputFile = new File(pdfFile.getParent(),textFileName); 64                     System.out.println("新檔案絕對路徑為:"+outputFile.getAbsolutePath()); 65                      66                   67                 } 68                 System.out.println("裝載檔案結束"); 69   70             71                System.out.println("開始寫到txt檔案中"); 72                // 檔案輸入資料流,寫入檔案倒textFile 73                output = new OutputStreamWriter(new FileOutputStream(outputFile),encoding); 74                System.out.println("寫入txt檔案結束"); 75                // PDFTextStripper來提取文本 76                PDFTextStripper stripper = null; 77                stripper = new PDFTextStripper(); 78                // 設定是否排序 79                stripper.setSortByPosition(sort); 80                // 設定起始頁 81                stripper.setStartPage(startPage); 82                // 設定結束頁 83                stripper.setEndPage(endPage); 84                // 調用PDFTextStripper的writeText提取並輸出文本 85                System.out.println("開始調用writeText方法"); 86                stripper.writeText(document, output); 87                System.out.println("調用writeText方法結束"); 88           }catch (Exception e) { 89                e.printStackTrace(); 90           }finally { 91               if (output != null) { 92                     // 關閉輸出資料流 93                     output.close(); 94                } 95                if (document != null) { 96                 // 關閉PDF Document 97                 document.close(); 98                } 99           }100      }101 }
View Code

有很多打樁的語句,可以自行去除。

6.遇到的問題及解決方案

1)一開始使用的並不是PDF2.0版本,而是1.8版(2.0版本還是實驗版本,故選用了早期的1.8版本)。但使用1.8版本,使用PDDocument.load(String)方法時,老是出現這個異常——“java.io.IOException: Push back buffer is full”。

解決方案:上述問題困擾了筆者很久。筆者為此重新複習了IO和NIO的一些知識,並查閱了PDFBox英文API文檔(1.8版本),均無解決思路。後大量查閱資料得知,這可能是1.8版本出現的bug。2.0版本修複了bug。改為2.0版本,果然就好了。需要提醒的是,2.0版本PDDocument.load()方法參數為File類型,不再是String類型。可以參閱官方API文檔。

PDFBox的使用——分頁提取PDF文本

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.