[英]Reading PDF content with itextsharp dll in VB.NET or C#
如何使用带有 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();
}
您无法按照自己的意愿使用iTextSharp读取和解析PDF的内容。
从iTextSharp的SourceForge教程中 :
您无法使用iText来“解析”现有的PDF文件,而只能每页“读取”它。
这是什么意思?
pdf格式只是一个放置文本和图形的画布,没有任何结构信息。 因此,PDF文件中没有任何“ iText对象”。 每个页面中可能会有许多“字符串”,但是您无法使用这些字符串来重建短语或段落。 可能会画出许多线,但是您不能基于这些线来检索Table对象。 简而言之:使用iText解析PDF文件的内容是不可能的。 将您的问题发布到新闻组news://comp.text.pdf上,也许您会从那些已经构建了可以解析PDF并提取其某些内容的工具的人那里得到一些答案,但是不要指望能够执行项目符号的工具转换为结构化文本。
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;
}
如果显示的文本是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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.