VB.NETまたはC#でitextsharpdllを使用してPDFコンテンツを読み取る


80

Pdfreaderクラスのitexsharpを使用してPDFコンテンツを読み取るにはどうすればよいですか。私のPDFには、プレーンテキストまたはテキストの画像が含まれている場合があります。


iTextSharpは、github:linkで「iText7for.NET」または「itext7-dotnet」と呼ばれるようになりました 。Nugetを使用してitex7をソリューションに追加することをお勧めします。
PeterHuber20年

回答:


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
これは解決策としてマークする必要があります!これは私にとって素晴らしい働きをします。
カーターメドリン2011

1
pdfReader.Close();の特定の理由。forループ内で発生しますか?
–Th00mÄs 2012

8
.Close()をまったく使用せずに使用する理由using (var pdfReader = ...) {}
Sebastian

2
また、静的メソッドであるASCIIEncoding.Convert必要Encoding.Convertがあります
Sebastian

上記のようなコードが必要な場合は、C#でPDFのテキストを読み取るための段階的な実装、ここにリンクがあります、qawithexperts.com / article / c
sharp /

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

他の答えはどれも私には役に立ちませんでした。それらはすべてiTextSharpのAGPLv5をターゲットにしているようです。FOSSバージョンへの参照SimpleTextExtractionStrategyLocationTextExtractionStrategyFOSSバージョンへの参照は見つかりませんでした。

これと組み合わせて非常に役立つかもしれない他の何か:

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

これにより、表示されるテキストFoo(bar)がPDFでエンコードされる場合、PDFからテキストのみのデータが抽出されます。(Foo\(bar\))TjこのメソッドはFoo(bar)、期待どおりに返されます。このメソッドは、生のpdfコンテンツから位置座標などの多くの追加情報を取り除きます。


1
5.xxテキスト抽出がiTextに概念実証としてのみ存在し、iTextSharpにはまったく存在していなかったのは、その通りです。そうは言っても、あなたが提示するコードは、非常に原始的に構築されたPDFでのみ機能します(ASCII風のエンコーディングとTjをテキスト描画演算子としてのみ使用するフォントを使用します)。非常に制御された環境(このようなプリミティブPDFのみを取得できるようにすることができます)では使用できますが、一般的には使用できません。
mkl 2014年

正しい正規表現は次のとおりです。(?<=()(。*?)(?=)Tj)
ディエゴ

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

PDFでこれを試してみると、「値をnullにすることはできません。パラメータ名:値」というエラーメッセージが表示されます。これが何であるかについて何か考えはありますか?
Avi 2011

sOut&= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader、i、its)。また、私はこのエラーについて何かを理解しました。ループから外して個々のページを解析すると、一方のページでは機能し、もう一方のページでは機能しません。私が知ることができる2つの違いは、問題のあるページに画像が含まれていることだけです(これは必要ありません)。
Avi 2011

PDFをご覧になりたい場合は、お送りします。
Avi 2011

.Net4.0とitexsharp5.1.2.0(ダウンロードしたばかり)を使用しています。あなたと同じ?
カーターメドリン2011

.Net3.5およびitexsharp5.1.1。更新して、解決されるかどうかを確認します。
Avi

5

私の場合、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ドキュメントにあるフォーマットを維持していませんが、キャリッジリターンが保持されていることを嬉しく思います。私の場合、テキストには十分な定数があり、必要な値を抽出することができました。


0

ここにShravankumarKumarの改善された答えがあります。テキスト行とその行の単語に基づいてPDF内の単語にアクセスできるように、ページ用に特別なクラスを作成しました。

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

カスタムクラス

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

これで、行ごとおよび単語インデックスごとに単語を取得できます。

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

または、Linqを使用して、特定の単語を含む行を検索します。

//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
質問はPDFファイルを読むことを求めています、あなたの答えはそれを作成することです!
AAA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.