无法使用 iTextSharp 读取 pdf 文件中特定位置的文本
Unable to read text in a specific location in a pdf file using iTextSharp
我被要求阅读 pdf 文本并做一些事情正在提取文本。我正在使用 iTextSharp 阅读 PDF。这里的问题是 PdfTextExtractor.GetTextFromPage 没有给我页面的所有内容。例如
在上面的 PDF 中,我无法阅读以蓝色突出显示的文本。其余字符我无法阅读。下面是执行上述操作的行
`string filePath = "myFile path";
PdfReader pdfReader = new PdfReader(filePath);
for (int page = 1; page<=1; page++)
{
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentPageText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);
}`
这里有什么建议吗?
我在 SO 中经历了很多查询和解决方案,但并不特定于此查询。
文本提取不提取这些文本的原因很简单:这些文本不是静态页面内容的一部分,而是表单字段!但是 "Text extraction" 在 iText(以及我知道的其他 PDF 库)中被认为是 "extraction of the text of the static page content"。因此,您错过的那些文本根本不受文本提取的影响。
如果您也想让表单字段值受制于您的文本提取代码,您首先必须展平 表单字段可视化。 "Flattening" 这里的意思是让它们成为静态页面内容的一部分,并删除它们所有的表单字段动态。
您可以在阅读完 PDF 后添加这一行
PdfReader pdfReader = new PdfReader(filePath);
用于拼合此 PDF 并将拼合后的 PDF 加载到 pdfReader
的代码,例如像这样:
MemoryStream memoryStream = new MemoryStream();
PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream);
pdfStamper.FormFlattening = true;
pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();
memoryStream.Position = 0;
pdfReader = new PdfReader(memoryStream);
从此重新初始化的 pdfReader
中提取文本也会为您提供表单字段中的文本。
不幸的是,扁平化的表单文本被添加到内容流的末尾。由于您选择的文本提取策略 SimpleTextExtractionStrategy
只需 returns 文本按绘制顺序排列,前表单字段内容将在最后提取。
您可以使用不同的文本提取策略来更改此设置,即替换此行:
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
使用 LocationTextExtractionStrategy
(iText 发行版的一部分)已经 returns 获得了更好的结果;不幸的是,表单字段值与我们认为在同一行的静态内容并不完全在同一基线上,因此出现了一些意想不到的换行符。
ITextExtractionStrategy strategy = new LocationTextExtractionStrategy();
使用 HorizontalTextExtractionStrategy
(来自 this answer,其中包含 Java 及其 C# 版本)结果更好。但是请注意,此策略并非普遍更好,请阅读答案文本中的警告。
ITextExtractionStrategy strategy = new HorizontalTextExtractionStrategy();
我被要求阅读 pdf 文本并做一些事情正在提取文本。我正在使用 iTextSharp 阅读 PDF。这里的问题是 PdfTextExtractor.GetTextFromPage 没有给我页面的所有内容。例如
在上面的 PDF 中,我无法阅读以蓝色突出显示的文本。其余字符我无法阅读。下面是执行上述操作的行
`string filePath = "myFile path";
PdfReader pdfReader = new PdfReader(filePath);
for (int page = 1; page<=1; page++)
{
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentPageText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);
}`
这里有什么建议吗?
我在 SO 中经历了很多查询和解决方案,但并不特定于此查询。
文本提取不提取这些文本的原因很简单:这些文本不是静态页面内容的一部分,而是表单字段!但是 "Text extraction" 在 iText(以及我知道的其他 PDF 库)中被认为是 "extraction of the text of the static page content"。因此,您错过的那些文本根本不受文本提取的影响。
如果您也想让表单字段值受制于您的文本提取代码,您首先必须展平 表单字段可视化。 "Flattening" 这里的意思是让它们成为静态页面内容的一部分,并删除它们所有的表单字段动态。
您可以在阅读完 PDF 后添加这一行
PdfReader pdfReader = new PdfReader(filePath);
用于拼合此 PDF 并将拼合后的 PDF 加载到 pdfReader
的代码,例如像这样:
MemoryStream memoryStream = new MemoryStream();
PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream);
pdfStamper.FormFlattening = true;
pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();
memoryStream.Position = 0;
pdfReader = new PdfReader(memoryStream);
从此重新初始化的 pdfReader
中提取文本也会为您提供表单字段中的文本。
不幸的是,扁平化的表单文本被添加到内容流的末尾。由于您选择的文本提取策略 SimpleTextExtractionStrategy
只需 returns 文本按绘制顺序排列,前表单字段内容将在最后提取。
您可以使用不同的文本提取策略来更改此设置,即替换此行:
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
使用
LocationTextExtractionStrategy
(iText 发行版的一部分)已经 returns 获得了更好的结果;不幸的是,表单字段值与我们认为在同一行的静态内容并不完全在同一基线上,因此出现了一些意想不到的换行符。ITextExtractionStrategy strategy = new LocationTextExtractionStrategy();
使用
HorizontalTextExtractionStrategy
(来自 this answer,其中包含 Java 及其 C# 版本)结果更好。但是请注意,此策略并非普遍更好,请阅读答案文本中的警告。ITextExtractionStrategy strategy = new HorizontalTextExtractionStrategy();