2010-04-28 178 views
3

我試圖通過Poppler及其(缺少)文檔獲得我的方式。用Poppler(C++)從PDF中提取文本

我想要做的是一件非常簡單的事情:打開PDF文件並閱讀其中的文本。然後我要處理文本,但這並不重要。

所以...我看到了poppler_page_get_text函數,它有用,但我必須指定一個選擇矩形,這不是很方便。是不是隻有一個非常簡單的功能,可以按順序輸出PDF文本(也許是逐行輸出?)。

+0

poppler源代碼包含兩個簡單的示例程序,它們在'./cpp/test'中說明了所有的功能。 – Jeroen 2016-02-25 11:11:37

回答

8

您應該能夠將選擇矩形設置爲頁面的pageSize/MediaBox並獲取所有文本。

我說應該是因爲在你開始想知道爲什麼你會對poppler_page_get_text的輸出感到驚訝之前,你應該知道如何在頁面上佈置文本。所有圖形均使用以後綴表示法表示的程序在頁面上進行佈局。爲了渲染頁面,該程序在空白頁面上執行。

程序中的操作可以包括改變顏色,位置,當前變換矩陣,繪製線,貝塞爾曲線等。文本由一系列始終包含在BT(開始文本)和ET(結束文本)中的文本運算符進行佈局。如何或在何處放置文本是由生成PDF的軟件自行決定。例如,對於打印驅動程序,代碼響應GDI調用DrawString並將其轉換爲文本繪圖操作。

如果幸運的話,頁面上的文本按照正常的字體使用順序排列,但許多生成PDF的程序並不那麼友好。例如Psroff,首先將所有純文本,然後是斜體文本,然後是粗體文本。單詞可能或不可以放在閱讀順序中。字體可能會重新編碼,以便'a'映射到'{'或其他。然後,您可能會有多個字符被單個字形替換的連字 - 最常見的字符是ae,oe,fi,flffl

隨着這一切的到來,提取文本的過程肯定是不平凡的,所以如果您看到文本提取質量差的結果,請不要感到驚訝。

我曾經使用過Acrobat 1.0和2.0中的文本提取工具 - 這是一個真正的挑戰。從記錄上來看

+1

非常感謝您的解釋。我想我會開始更廣泛地閱讀PDF的編碼方式。或嘗試重新思考我的策略一點點:) :) 乾杯 nico – nico 2010-05-01 11:42:56

3

,我使用poppler的現在用這個小程序

#include <iostream> 

#include "poppler-document.h" 
#include "poppler-page.h" 
using namespace std; 

int main() 
{ 
    poppler::document *doc = poppler::document::load_from_file("./CMI2APIDocV1.4.pdf"); 
    const int pagesNbr = doc->pages(); 
    cout << "page count: " << pagesNbr << endl; 

    for (int i = 0; i < pagesNbr; ++i) 
     cout << doc->create_page(i)->text().to_latin1().c_str() << endl; 
} 

// g++ -I/usr/include/poppler/cpp/ -c poppler.cpp 
// g++ -I/usr/include/poppler/cpp poppler.o /usr/lib/x86_64-linux-gnu/libpoppler-cpp.a /usr/lib/x86_64-linux-gnu/libpoppler.a /usr/lib/x86_64-linux-gnu/liblcms2.so  /usr/lib/x86_64-linux-gnu/libfontconfig.a /usr/lib/x86_64-linux-gnu/libjpeg.a /usr/lib/x86_64-linux-gnu/libfreetype.a  /usr/lib/x86_64-linux-gnu/libexpat.a /usr/lib/x86_64-linux-gnu/libz.a 

我有個結果相當滿意,到目前爲止,除陣列和純文本「電子表格」恢復原狀,有時單個單元可能跨越多條線。 (如果有人知道如何避免這種情況?)

+0

有一個相關的「電子表格」類型的數據的問題:[從PDF文件以編程方式提取表?](http://stackoverflow.com /問題/ 488089 /提取桌從 - PDF的文件,編程)。 – 2016-01-28 12:57:14