Pdfreader 클래스를 사용하여 itextsharp로 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();
}
답변
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를 대상으로하는 것 같습니다. 나는에 대한 참조 찾을 수 없을 수 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