2010-03-31 70 views

回答

17

您不能讀取和使用iTextSharp的解析PDF的內容,就像你想。

從iTextSharp的的SourceForge tutorial

你不能 '解析' 利用iText現有的PDF文件 ,你只能 '讀' 每頁它 頁。

這是什麼意思?

pdf格式只是一個畫布,其中 文本和圖形放置沒有 任何結構信息。因此, 的PDF文件中沒有任何「iText-objects」。在每個頁面會有 可能是一個數字「條件」的,但 你不能重建一個短語或使用這些字符串一個 段落。有 可能是多條線路的繪製, 但你不能檢索基於這些線表對象 。總之: 解析PDF文件的內容是 不可能與iText。發表您的 問題在新聞組 消息://comp.text.pdf,也許你 將人得到一些答案是 建立了一個可以解析PDF 並提取部分內容的工具,但 不要指望將執行 防彈轉換爲結構化 文本的工具。

+3

+1感謝您閱讀本教程的摘錄。這是我見過的關於PDF文件的唯一最具信息量的解釋(真實的啓示)。在閱讀之前,我曾經認爲PDF文件中存在某種類似Word的結構。 – Sabuncu 2013-10-26 20:11:54

+0

@Sabuncu很高興能夠幫助! – 2013-10-27 02:30:06

156
using iTextSharp.text.pdf; 
using iTextSharp.text.pdf.parser; 
using System.IO; 

public string ReadPdfFile(string fileName) 
{ 
    StringBuilder text = new StringBuilder(); 

    if (File.Exists(fileName)) 
    { 
     PdfReader pdfReader = new PdfReader(fileName); 

     for (int page = 1; page <= pdfReader.NumberOfPages; page++) 
     { 
      ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
      string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); 

      currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); 
      text.Append(currentText); 
     } 
     pdfReader.Close(); 
    } 
    return text.ToString(); 
} 
+14

這應該被標記爲解決方案!這對我很好。 – 2011-09-01 17:41:29

+0

同意,這是有效的,將其標記爲答案。 – skimania 2011-10-03 16:12:00

+0

完美地工作,謝謝一堆! – JoseMarmolejos 2012-01-12 21:47:49

6

這是基於ShravankumarKumar的解決方案VB.NET解決方案。

這隻會給你的文字。這些圖像是一個不同的故事。

Public Shared Function GetTextFromPDF(PdfFileName As String) As String 
    Dim oReader As New iTextSharp.text.pdf.PdfReader(PdfFileName) 

    Dim sOut = "" 

    For i = 1 To oReader.NumberOfPages 
     Dim its As New iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy 

     sOut &= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader, i, its) 
    Next 

    Return sOut 
End Function 
+0

當我嘗試這個在我的PDF上,它給了我錯誤消息,「值不能爲空。參數名稱:值」。任何想法這是關於什麼? – Avi 2011-09-01 19:38:35

+0

你能告訴我哪一行代碼會給你這個錯誤嗎? – 2011-09-01 19:43:50

+0

sOut&= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader,i,its)。 另外,我想出了一些關於這個錯誤的信息。如果我將它從循環中解析出來並解析單個頁面,它可以在一個頁面上運行,而不在另一個頁面上運行。我可以告訴的兩個唯一區別是有問題的頁面上有圖像(我不需要)。 – Avi 2011-09-01 19:53:09

0
Public Sub PDFTxtToPdf(ByVal sTxtfile As String, ByVal sPDFSourcefile As String) 
     Dim sr As StreamReader = New StreamReader(sTxtfile) 
    Dim doc As New Document() 
    PdfWriter.GetInstance(doc, New FileStream(sPDFSourcefile, FileMode.Create)) 
    doc.Open() 
    doc.Add(New Paragraph(sr.ReadToEnd())) 
    doc.Close() 
End Sub 
10

LGPL/FOSS iTextSharp的4.x的

var pdfReader = new PdfReader(path); //other filestream etc 
byte[] pageContent = _pdfReader .GetPageContent(pageNum); //not zero based 
byte[] utf8 = Encoding.Convert(Encoding.Default, Encoding.UTF8, pageContent); 
string textFromPage = Encoding.UTF8.GetString(utf8); 

其他答案沒有一個是對我有用的,他們似乎都瞄準iTextSharp的的AGPL V5。我永遠無法在FOSS版本中找到對SimpleTextExtractionStrategyLocationTextExtractionStrategy的任何引用。

別的東西,可能結合是非常有用的這個:

const string PdfTableFormat = @"\(.*\)Tj"; 
Regex PdfTableRegex = new Regex(PdfTableFormat, RegexOptions.Compiled); 

List<string> ExtractPdfContent(string rawPdfContent) 
{ 
    var matches = PdfTableRegex.Matches(rawPdfContent); 

    var list = matches.Cast<Match>() 
     .Select(m => m.Value 
      .Substring(1) //remove leading (
      .Remove(m.Value.Length - 4) //remove trailing)Tj 
      .Replace(@"\)", ")") //unencode parens 
      .Replace(@"\(", "(") 
      .Trim() 
     ) 
     .ToList(); 
    return list; 
} 

這將從PDF中提取純文本數據,如果顯示的文本是Foo(bar)它將在PDF被編碼爲(Foo\(bar\))Tj,如預期的那樣該方法將返回Foo(bar)。此方法將從原始pdf內容中去除大量附加信息,例如位置座標。

+1

你是對的,在5.x.x文本提取出現在iText之前,僅僅是作爲概念驗證和iTextSharp完全沒有。這就是說,你所提供的代碼只能在非常原始的內置PDF中使用(使用帶ASCII'ish編碼的字體和僅作爲文本繪製操作符的** Tj **)。它可能適用於非常受控制的環境(您可以確保只獲取這些原始PDF),但通常不會。 – mkl 2014-11-04 16:55:43

4

在我來說,我只是想從PDF文檔的特定區域中的文本,所以我用周圍區域的矩形,並從中提取的文本。在下面的示例中,座標是針對整個頁面的。我沒有PDF製作工具,所以當需要將矩形縮小到特定位置時,我會在座標處進行一些猜測,直到找到該區域。

Rectangle _pdfRect = new Rectangle(0f, 0f, 612f, 792f); // Entire page - PDF coordinate system 0,0 is bottom left corner. 72 points/inch 
RenderFilter _renderfilter = new RegionTextRenderFilter(_pdfRect); 
ITextExtractionStrategy _strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), _filter); 
string _text = PdfTextExtractor.GetTextFromPage(_pdfReader, 1, _strategy); 

正如上述意見得到的文本不保持任何的PDF文檔中的格式的注意,但是我很高興,它沒有保留回車。在我的情況下,文本中有足夠的常量,可以提取我需要的值。