Як я можу прочитати вміст PDF за допомогою itextsharp за допомогою класу Pdfreader. Мій PDF може містити звичайний текст або зображення тексту.
Як я можу прочитати вміст PDF за допомогою itextsharp за допомогою класу Pdfreader. Мій 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);
Жодна з інших відповідей не була для мене корисною, вони, схоже, націлені на AGPL v5 iTextSharp. Я ніколи не міг знайти жодного посилання на 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;
}
Це витягне лише текстові дані з PDF-файлу, якщо відображений текст Foo(bar)
буде закодовано в PDF як (Foo\(bar\))Tj
, цей метод повернеться, Foo(bar)
як очікувалося. Цей метод вилучить багато додаткової інформації, наприклад координати місцезнаходження, із необробленого вмісту PDF.
Ось рішення VB.NET на основі рішення ShravankumarKumar.
Це надасть ТІЛЬКИ текст. Зображення - це вже інша історія.
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