web-dev-qa-db-ja.com

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

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

74
user221185
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();
}
175

希望どおりにiTextSharpを使用してPDFの内容を読み取ったり解析したりすることはできません。

ITextSharpの SourceForgeチュートリアル から:

ITextを使用して既存のPDFファイルを「解析」することはできません。ページごとに「読み取り」のみできます。

これは何を意味するのでしょうか?

Pdf形式は、構造情報なしでテキストとグラフィックが配置される単なるキャンバスです。そのため、PDFファイルには「iTextオブジェクト」はありません。各ページにはおそらく「文字列」がいくつかありますが、これらの文字列を使用してフレーズや段落を再構築することはできません。おそらく多数の線が描かれていますが、これらの線に基づいてテーブルオブジェクトを取得することはできません。要するに、PDFファイルのコンテンツの解析は、iTextでは不可能です。ニュースグループnews://comp.text.pdfに質問を投稿すると、おそらくPDFを解析してその内容の一部を抽出できるツールを構築した人々からいくつかの回答が得られますが、期待しないでください。構造化テキストへの防弾変換を実行するツール。

19
Jay Riggs

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バージョンでSimpleTextExtractionStrategyまたはLocationTextExtractionStrategyへの参照が見つかりませんでした。

これに関連して非常に役立つ可能性のある他の何か:

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コンテンツから位置座標などの多くの追加情報を取り除きます。

15
Chris Marisic

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
6
Carter Medlin

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

5
voidmain
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
0
Raja