C# iTextSharp PDFReader 总是从 PDF 的开头读取
Posted
技术标签:
【中文标题】C# iTextSharp PDFReader 总是从 PDF 的开头读取【英文标题】:C# iTextSharp PDFReader Reads From Beginning of PDF Always 【发布时间】:2016-12-07 20:29:37 【问题描述】:我正在使用 iTextSharp PDFReader 读取一个有 18 页的 pdf 文件,但每次我增加页码时,它都会从 pdf 的开头开始,而不是只读取那个特定的页面。如果我将“x”设置为 pdfReader.NumberOfPages 值,它只会读取最后一页。我想单独阅读每一页并将数据添加到我的字符串列表中。我也在浏览一个文件夹,阅读每个 pdf 文件,但我一开始只测试一个。
List<string> s = new List<string>();
while (z < filePaths.Count())
PdfReader pdfReader = new PdfReader(filePaths[z]);
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
for (int x = 1; x <= pdfReader.NumberOfPages; x++)
string currentText = "";
currentText = PdfTextExtractor.GetTextFromPage(pdfReader, x, strategy);
s.Add(currentText);
z++;
pdfReader.Close();
【问题讨论】:
它是否总是只读取第一页,除了最后一页,还是读取从第一页到第 x 页的所有内容?底层的主力方法ProcessContent<E>(int pageNumber, E renderListener)
显然应该做你想做的......你使用哪个版本的 ITextSharp?
使用5.5.10.0,总是从第一页开始,一直读到第x页
只是为了确保...您是否希望 s
在外部循环完成时包含所有文件的所有页面,每个列表项有一页文本?
是的,我想逐页阅读 pdf 并将每一页文本作为列表项插入。
【参考方案1】:
之前的所有答案都非常接近,即您正确地将其归咎于某种状态问题。
唯一缺少的部分是 strategy
变量记住了它的状态。调用GetTextFromPage
后,您的策略对象不会刷新其现有内容。
所以诀窍是在循环内实例化您的strategy
:
for (int x = 1; x <= pdfReader.NumberOfPages; x++)
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentText = "";
currentText = PdfTextExtractor.GetTextFromPage(pdfReader, x, strategy);
s.Add(currentText);
【讨论】:
【参考方案2】:通过从这一行删除策略 PdfTextExtractor.GetTextFromPage(pdfReader, x, strategy)
使其工作
static void Main(string[] args)
List<string> filePaths = new List<string>();
filePaths.Add("C:\\temp\\pe\\ACN-ONFBG-010-R-EN-ONT (1364).pdf");
filePaths.Add("C:\\temp\\pe\\ACN-ONFBG-010-R-UN-NOR (1364).pdf");
filePaths.Add("C:\\temp\\pe\\ACN-ONFBG-010-R-UN-SOU (1364).pdf");
List<string> results = doit(filePaths);
string stall = "stall";
private static List<string> doit(List<string> filePaths)
List<string> s = new List<string>();
int z = 0;
while (z < filePaths.Count())
PdfReader pdfReader = new PdfReader(filePaths[z]);
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
for (int x = 1; x <= pdfReader.NumberOfPages; x++)
string currentText = "";
currentText = PdfTextExtractor.GetTextFromPage(pdfReader, x);
s.Add(currentText);
z++;
pdfReader.Close();
return s;
【讨论】:
调用默认值LocationTextExtractionStrategy
,而不是SimpleTextExtractionStrategy
。显然,后者没有正确处理页面边界 - 不知道是根据定义还是由于错误。
无论如何它都能正常工作。它从不工作到工作,这是我让它工作的唯一改变。在这一点上,我倾向于一个错误。布鲁诺经常在这里回答与 iText 相关的问题,希望他能看到这个并参与进来。
这就是我投票的原因,尽管我的回答下面的讨论得出了相同的结论 :) 让我们希望 iText 的人读到这个,他们可能会解释或修复。
很有趣......看起来每当传递第三个参数时,它就会停止工作。我刚刚通过将strategy
设置为LocationTextExtractionStrategy
再次尝试,我又回到了操作员发布的原始行为。
这将在这种情况下发挥作用,因为 iText 将在内部为每个页面单独创建一个策略(即每个 GetTextFromPage
调用)。见***.com/a/41038493/2065017【参考方案3】:
我怀疑是读者状态问题。尝试在循环之前打开 PdfReader 一次以获取页数。将页数存储在变量中。使用该变量作为循环的上限。然后在循环中,为每个页面实例化一个新的 PdfReader,在每次迭代后处理它。
EDIT:原来是文本提取策略是罪魁祸首。它以某种方式保留状态。始终在调用 GetTextFromPage
之前实例化一个新的 SimpleTextExtractionStrategy
,或者省略 strategy
参数 - 然后将在内部创建 ITextExtractionStrategy
的默认实现的新实例。
【讨论】:
我尝试了以下,仍然得到与上面相同的结果: for (int x = 1; x 很奇怪。我们应该确保该 PDF 的页面字典没有损坏...您可以尝试使用任何其他 PDF 文件吗?并且您说当您将x
设置为页数时它会起作用:如果您将其设置为 7,会发生什么?
我可以使用另一个字符串列表并获取“s”的最后一个索引,但我担心它可能不包含 pdf 中的所有数据,因为字符串长度是有限的,我不确定这些pdf中的任何一个可能有多少页
让我澄清一下,如果我将 x 设置为 18,则此 pdf 中的页数,它只读取第 18 页,而不是整个 pdf。如果我将它设置为 7,它会读取第 7 页,然后在下一个循环中读取第 7 和第 8 页,依此类推...
这使它起作用了。我之前尝试过,但得到了相同的结果,我认为每次阅读页面时调用 PDFReader 并处理它可以解决问题以上是关于C# iTextSharp PDFReader 总是从 PDF 的开头读取的主要内容,如果未能解决你的问题,请参考以下文章
求助,c#如何利用iTextSharp.dll读取PDF的书签信息
Powershell itextSharp PDF打中文水印