Pdfreaderクラスのitexsharpを使用してPDFコンテンツを読み取るにはどうすればよいですか。私のPDFには、プレーンテキストまたはテキストの画像が含まれている場合があります。
Pdfreaderクラスのitexsharpを使用してPDFコンテンツを読み取るにはどうすればよいですか。私のPDFには、プレーンテキストまたはテキストの画像が含まれている場合があります。
回答:
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();
}
using (var pdfReader = ...) {}
ASCIIEncoding.Convert
必要Encoding.Convert
があります
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バージョンへの参照SimpleTextExtractionStrategy
やLocationTextExtractionStrategy
FOSSバージョンへの参照は見つかりませんでした。
これと組み合わせて非常に役立つかもしれない他の何か:
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コンテンツから位置座標などの多くの追加情報を取り除きます。
これは、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ドキュメントの特定の領域からのテキストが必要だったので、その領域の周りに長方形を使用して、そこからテキストを抽出しました。以下のサンプルでは、座標はページ全体のものです。私は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ドキュメントにあるフォーマットを維持していませんが、キャリッジリターンが保持されていることを嬉しく思います。私の場合、テキストには十分な定数があり、必要な値を抽出することができました。
ここに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();
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