Đọc nội dung PDF với dll itextsharp trong VB.NET hoặc C #


80

Làm cách nào để đọc nội dung PDF với itextsharp với lớp Pdfreader. PDF của tôi có thể bao gồm Văn bản thuần túy hoặc Hình ảnh của văn bản.


iTextSharp hiện được gọi là "iText 7 cho .NET" hoặc "itext7-dotnet" trên github: link . Bạn nên thêm itext7 với Nuget vào giải pháp của mình.
Peter Huber

Câu trả lời:


184
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();
}

16
Đây nên được đánh dấu là giải pháp! Điều này làm việc tuyệt vời cho tôi.
Carter Medlin

1
Bất kỳ lý do cụ thể nào pdfReader.Close (); xảy ra bên trong vòng lặp for?
00

8
tại sao sử dụng .Close () ở tất cả và khôngusing (var pdfReader = ...) {}
Sebastian

2
Ngoài ra, ASCIIEncoding.Convertnên Encoding.Convertvì nó là một phương pháp tĩnh
Sebastian

Nếu ai cần mã tương tự như trên, hãy thực hiện từng bước để đọc văn bản pdf bằng C #, đây là liên kết, qawithexperts.com/article/c-sharp/… cảm ơn
user3559462

15

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 nào khác hữu ích với tôi, tất cả dường như đều nhắm mục tiêu AGPL v5 của iTextSharp. Tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào đến SimpleTextExtractionStrategyhoặc LocationTextExtractionStrategytrong phiên bản FOSS.

Một cái gì đó khác có thể rất hữu ích cùng 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;
}

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


1
Bạn nói đúng, trước khi trích xuất văn bản 5.xx xuất hiện trong iText chỉ đơn thuần là bằng chứng về khái niệm và trong iTextSharp thì không. Đ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 rất nguyên thủy (sử dụng phông chữ có mã hóa ASCII và Tj chỉ là toán tử vẽ văn bản). Nó có thể sử dụng được trong các môi trường được kiểm soát rất chặt chẽ (trong đó bạn có thể đảm bảo chỉ nhận được các tệp PDF nguyên thủy như vậy) nhưng nói chung thì không.
mkl

Biểu thức Regex đúng là: (? <= () (. *?) (? =) Tj)
Diego

6

Đây là giải pháp VB.NET dựa trên giải pháp của ShravankumarKumar.

Điều này sẽ CHỈ 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

Khi tôi thử điều này trên tệp PDF của mình, nó đưa ra 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 kỳ ý tưởng về những gì đây là về?
Avi

sOut & = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage (oReader, i, its). 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ú pháp các trang riêng lẻ, nó sẽ 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 trang mà tôi có thể biết là trang có vấn đề có hình ảnh trên đó (mà tôi không cần).
Avi

Nếu bạn muốn xem bản PDF, tôi có thể gửi cho bạn.
Avi

Tôi đang sử dụng .Net 4.0 và itextsharp 5.1.2.0 (Vừa tải xuống). Với bạn cũng vậy?
Carter Medlin

.Net 3.5 và itextsharp 5.1.1. Tôi sẽ cập nhật và xem liệu nó có được giải quyết hay không.
Avi

5

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 nên 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 dưới đây, tọa độ dành cho toàn bộ trang. Tôi không có công cụ tạo PDF vì vậy 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 tọa độ cho đến khi tìm thấy khu vực.

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 ý bởi các nhận xét ở 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ó đã giữ được ký tự xuống dòng. Trong trường hợp của tôi, có đủ hằng số trong văn bản để tôi có thể trích xuất các giá trị mà tôi yêu cầu.


0

Đây là một câu trả lời cải tiến của ShravankumarKumar. Tôi đã tạo các lớp đặc biệt cho các trang để bạn có thể truy cập các từ trong pdf dựa trên các hàng văn bản và từ trong hàng đó.

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

//create a list of pdf pages
var pages = new List<PdfPage>();

//load the pdf into the reader. NOTE: path can also be replaced with a byte array
using (PdfReader reader = new PdfReader(path))
{
    //loop all the pages and extract the text
    for (int i = 1; i <= reader.NumberOfPages; i++)
    {
        pages.Add(new PdfPage()
        {
           content = PdfTextExtractor.GetTextFromPage(reader, i)
        });
    }
}

//use linq to create the rows and words by splitting on newline and space
pages.ForEach(x => x.rows = x.content.Split('\n').Select(y => 
    new PdfRow() { 
       content = y,
       words = y.Split(' ').ToList()
    }
).ToList());

Các lớp tùy chỉnh

class PdfPage
{
    public string content { get; set; }
    public List<PdfRow> rows { get; set; }
}


class PdfRow
{
    public string content { get; set; }
    public List<string> words { get; set; }
}

Bây giờ bạn có thể lấy từng từ theo hàng và chỉ mục từ.

string myWord = pages[0].rows[12].words[4];

Hoặc sử dụng Linq để tìm các hàng có chứa một từ cụ thể.

//find the rows in a specific page containing a word
var myRows = pages[0].rows.Where(x => x.words.Any(y => y == "myWord1")).ToList();

//find the rows in all pages containing a word
var myRows = pages.SelectMany(r => r.rows).Where(x => x.words.Any(y => y == "myWord2")).ToList();

-1
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

1
Câu hỏi là yêu cầu đọc một tệp PDF, câu trả lời của bạn là tạo một tệp!
AaA
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.