2010-03-31 65 views

Trả lời

17

Bạn không thể đọc và phân tích nội dung của tệp PDF bằng iTextSharp như bạn muốn.

Từ iTextSharp của SourceForge tutorial:

Bạn có thể không phải là 'phân tích' một tập tin PDF sẵn có sử dụng iText, bạn chỉ có thể 'đọc' nó trang mỗi trang.

này có nghĩa là gì?

Định dạng pdf chỉ là canvas nơi văn bản và đồ họa được đặt mà không cần bất kỳ thông tin cấu trúc nào. Vì vậy, không có bất kỳ 'đối tượng iText' nào trong tệp PDF . Trong mỗi trang sẽ có có thể là một số 'Chuỗi', nhưng bạn không thể tạo lại cụm từ hoặc đoạn bằng các chuỗi này. Có có thể là một số dòng được vẽ, nhưng bạn không thể truy xuất Bảng đối tượng dựa trên những dòng này. Tóm lại: phân tích cú pháp nội dung của tệp PDF là KHÔNG PHẢI với iText. Đăng câu hỏi của bạn trên nhóm tin tin tức: //comp.text.pdf và có thể bạn sẽ nhận được một số câu trả lời từ những người đó đã xây dựng các công cụ có thể phân tích cú pháp PDF và trích xuất một số nội dung của nó, nhưng không mong đợi các công cụ sẽ thực hiện chuyển đổi chống đạn thành văn bản được cấu trúc.

+3

+1 Cảm ơn bạn đã trích đoạn từ hướng dẫn. Đó là đoạn giải thích đơn giản nhất (mặc khải, thực sự) mà tôi từng thấy về các tệp PDF. Trước khi đọc nó, tôi đã từng nghĩ rằng có một loại cấu trúc giống như Word có trong các tệp PDF. – Sabuncu

+0

@Sabuncu Vui mừng được giúp đỡ! –

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

Điều này sẽ được đánh dấu là giải pháp! Điều này làm việc tuyệt vời cho tôi. –

+0

Đồng ý, công trình này, đánh dấu nó là câu trả lời. – skimania

+0

Hoạt động hoàn hảo, cảm ơn một đống! – JoseMarmolejos

6

Dưới đây là một giải pháp VB.NET dựa trên giải pháp ShravankumarKumar của.

CHỈ sẽ cung cấp cho bạn văn bản. Những hình ảnh là một câu chuyện khác nhau.

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

Khi tôi thử cái này trên tệp PDF của tôi, nó cung cấp cho tôi thông báo lỗi "Giá trị không được rỗng. Tên thông số: giá trị". Bất cứ ý tưởng gì về điều này? – Avi

+0

Bạn có thể cho tôi biết dòng mã nào cung cấp cho bạn lỗi đó không? –

+0

sOut & = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage (oReader, i, của nó). Ngoài ra, tôi đã tìm ra điều gì đó về lỗi này. Nếu tôi lấy nó ra khỏi vòng lặp và phân tích các trang riêng lẻ, nó hoạt động trên một trang chứ không phải trang khác. Sự khác biệt duy nhất giữa hai mà tôi có thể nói là trang có vấn đề có hình ảnh trên đó (mà tôi không cần). – Avi

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); 

Không có câu trả lời khác là hữu ích với tôi, tất cả dường như nhắm vào v5 AGPL của iTextSharp. Tôi không bao giờ có thể tìm thấy bất kỳ tham chiếu nào đến SimpleTextExtractionStrategy hoặc LocationTextExtractionStrategy trong phiên bản FOSS.

Cái gì khác mà có thể rất hữu ích trong việc kết hợp với điều này:

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; 
} 

này sẽ trích xuất các văn bản chỉ dữ liệu từ PDF, nếu văn bản được hiển thị là Foo(bar) nó sẽ được mã hóa trong PDF như (Foo\(bar\))Tj, phương pháp này sẽ trả lại Foo(bar) như mong đợi. Phương pháp này sẽ loại bỏ rất nhiều thông tin bổ sung như toạ độ vị trí từ nội dung pdf thô.

+1

Bạn đã đúng, trước khi trích xuất văn bản 5.x.x đã có trong iText đơn thuần là bằng chứng-khái niệm và trong iTextSharp thì không hề. Điều đó đang được nói, mã bạn trình bày chỉ hoạt động trong các tệp PDF được xây dựng sơ bộ (sử dụng phông chữ với mã hóa ASCII và ** Tj ** làm toán tử vẽ văn bản). Nó có thể được sử dụng trong các môi trường được kiểm soát (trong đó bạn có thể đảm bảo chỉ nhận được các tệp PDF nguyên thủy) nhưng không thể nói chung. – mkl

4

Trong trường hợp của tôi, tôi chỉ muốn văn bản từ một khu vực cụ thể của tài liệu PDF vì vậy tôi đã sử dụng một hình chữ nhật xung quanh khu vực và trích xuất văn bản từ đó. Trong mẫu bên dưới, tọa độ dành cho toàn bộ trang.Tôi không có các công cụ soạn thảo PDF nên khi đến lúc thu hẹp hình chữ nhật đến vị trí cụ thể, tôi đã đoán một vài lần tại các tọa độ cho đến khi khu vực được tìm thấy.

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); 

Như đã lưu ý ở trên, văn bản kết quả không duy trì bất kỳ định dạng nào được tìm thấy trong tài liệu PDF, tuy nhiên tôi rất vui vì nó đã duy trì lợi nhuận vận chuyển. Trong trường hợp của tôi có đủ hằng số trong văn bản mà tôi có thể trích xuất các giá trị mà tôi yêu cầu.

Các vấn đề liên quan