Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# iText7以错误的顺序读取行_C#_Itext7 - Fatal编程技术网

C# iText7以错误的顺序读取行

C# iText7以错误的顺序读取行,c#,itext7,C#,Itext7,我试图读出一个pdf文档表,但我面临一个问题 如果我定期打开PDF 它显示为: item[tab]item[tab]item[tab]item[tab]item item[tab]item[tab]item[tab]item[tab]item item[tab]item[tab]item[tab]item[tab]item 我使用以下方法转换PDF: StringBuilder result = new StringBuilder(); PdfDocument pdfDoc = new Pdf

我试图读出一个pdf文档表,但我面临一个问题

如果我定期打开PDF 它显示为:

item[tab]item[tab]item[tab]item[tab]item
item[tab]item[tab]item[tab]item[tab]item
item[tab]item[tab]item[tab]item[tab]item
我使用以下方法转换PDF:

StringBuilder result = new StringBuilder();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC));

LocationTextExtractionStrategy strategy = new LocationTextExtractionStrategy();

PdfCanvasProcessor parser = new PdfCanvasProcessor(strategy);
for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++)
{
    result.AppendLine("INFO_START_PAGE");
    string output = PdfTextExtractor.GetTextFromPage(pdfDoc.GetPage(i));
    /*Note, in the GetTextFromPage i replaced the method to output [tab] instead of a regular space on 
    big spaces*/
    foreach(string data in output.Replace("\r\n", "\n").Replace("\n", "×").Split('×'))
    {
        result.AppendLine(data.Trim().Replace("   ", "[tab]"));
    }

    result.AppendLine("INFO_END_PAGE");
}

pdfDoc.Close();
return result.ToString();
有没有办法解决这个问题

提取为

阿蒂克尔纳。奥姆施里金安塔尔酒店 佩尔斯图克·科斯滕 VERHUUR L.GELEVERDE ARBEID PDC 8欧元43,70欧元349,60欧元 VERHUUR O.GELEVERDE ARBEID PDC 3 60,95欧元182,85欧元 VERHUUR L.L.GELEVERDE ARBEID EM 24 € 32,20 € 772,80 首先,为什么会这样 正如在对问题的评论中推测的那样,确实存在一个小的垂直台阶,在所有行中,前三列设置在相同的垂直位置,后两列的垂直位置略有不同

行第一列y最后列y 标题行536 535.893 第一排516516.229 第二排495 495.478 第三排475 474.788 人们特别认识到,通过文本提取中断的行是其中y位置的小数点前数字不同于536 vs 535、475 vs 474的行,而具有相等小数点前数字的行没有中断

这是因为类TextChunkLocationDefaultImp在默认情况下用于存储文本块位置和比较这些位置的方法,它存储块的y位置,实际上是块的一个抽象,也适用于未在整数变量private readonly int distvertical和测试中水平写入的文本方法SameLine要求距离垂直值相等

命名空间iText.Kernel.Pdf.Canvas.Parser.Listener{ 内部类TextChunkLocationDefaultImp:ITextChunkLocation{ ... ///方向单位向量的垂直距离,即未旋转坐标系中的Y位置。 /// /// ///方向单位向量的垂直距离,即未旋转坐标系中的Y位置。 ///我们四舍五入到最接近的整数来处理比较浮点数的模糊性。 /// 私有只读int; ... ///要比较的位置 ///如果此位置与另一个位置在同一条线上,则为true 公共虚拟bool SameLineITextChunkLocation@as{ ... float dist垂直度diff=distvertical-@as.distvertical; 如果dist垂直度diff==0{ 返回true; } ... } ... } } 实际上,如果比较的文本块中有一个长度为零,则向下的SameLine允许一个小偏差。显然,长度为零的语块有时被用作变音标记,这种标记有时被应用于不同的高度。不过,在您的示例文件中,这并不重要

如何修复它 如上所述,问题是由TextChunkLocationDefaultImp.SameLine的行为造成的。因此,我们必须改变这种行为。但是,通常我们不想更改iText类本身的代码

幸运的是,LocationTextExtractionStrategy有一个构造函数,允许注入ITextChunkLocationStrategy实现,即ITextChunkLocation实例的工厂对象

因此,对于我们的任务,我们必须编写一个不那么严格的替代ITextChunkLocation实现,以及一个生成ITextChunkLocation实现实例的ITextChunkLocationStrategy实现

不幸的是,TextChunkLocationDefaultImp是iText的内部变量,并且有许多私有变量。因此,我们不能简单地从它派生实现,而是必须将它作为一个整体进行复制和粘贴,并将更改应用于该副本

因此,

类LaxTextChunkLocationStrategy:LocationTextExtractionStrategy.ITextChunkLocationStrategy { 公共场所选址策略 { } 公共虚拟ITextChunkLocation CreateLocation TextRenderInfo renderInfo,线段基线 { 返回新的TextChunkLocationLaxImpbaseline.GetStartPoint、baseline.GetEndPoint、renderInfo.GetSingleSpaceWidth; } } 类TextChunkLocationLaxImp:ITextChunkLocation { 私有常量浮点变音符号允许的垂直偏差=2; 私有只读向量定位; 专用只读向量结束位置; 私有只读向量方向向量; 私有只读int方向大小; 私有只读int; 私有只读浮点启动; 私有只读浮点数; 私有只读浮点字符空间宽度; public TextChunkLocation LaximpVector startLocation、Vector endLocation、float charSpaceWidth { this.startolocation=startolocation; this.endLocation=endLocation; this.charSpaceWidth=charSpaceWidth; Vector oVector=endLocation.oc 反倾销; 如果oVector.Length==0 { oVector=新向量1,0,0; } 方向向量=OVERECTOR.规格化; OrientationMagnite=intMath.Atan2orientationVector.GetVector.I2,orientationVector.GetVector.I1*1000; 向量原点=新向量0,0,1; DistVertical=intstartLocation.Subtractorigin.CrossOriginationVector.GetVector.I3; distParallelStart=orientationVector.dotstarlocation; distParallelEnd=方向向量.DotendLocation; } 公共虚拟国际定位 { 返回方向大小; } 公共虚拟整数域 { 返回垂直; } 公共虚拟浮点数启动 { 返回并启动; } 公共虚拟浮点数 { 返回端; } 公共虚拟矢量定位 { 返回定位; } 公共虚拟向量GetEndLocation { 返回端定位; } 公共虚拟浮点GetCharSpaceWidth { 返回字符空间宽度; } 公共虚拟bool SameLineITextChunkLocation@as { 如果方向重要性!=@as.orientationmagnity { 返回false; } int dist垂直度diff=distvertical-@as.distvertical; 如果数学横坐标垂直度差<2 { 返回true; } LineSegment mySegment=新的LineSegment位置、结束位置; 线段otherSegment=新建LineSegment@as.GetStartLocation,@as.GetEndLocation; 返回数学横坐标垂直度差 提取为

Omschrijving Aantal美术馆 佩尔斯图克·科斯滕 VERHUUR L.GELEVERDE ARBEID PDC 8欧元43,70欧元349,60欧元 VERHUUR O.GELEVERDE ARBEID PDC 3 60,95欧元182,85欧元 VERHUUR L.L.GELEVERDE ARBEID EM 24 € 32,20 € 772,80 首先,为什么会这样 正如在对问题的评论中推测的那样,确实存在一个小的垂直台阶,在所有行中,前三列设置在相同的垂直位置,后两列的垂直位置略有不同

行第一列y最后列y 标题行536 535.893 第一排516516.229 第二排495 495.478 第三排475 474.788 人们特别认识到,通过文本提取中断的行是其中y位置的小数点前数字不同于536 vs 535、475 vs 474的行,而具有相等小数点前数字的行没有中断

这是因为类TextChunkLocationDefaultImp在默认情况下用于存储文本块位置和比较这些位置的方法,它存储块的y位置,实际上是块的一个抽象,也适用于未在整数变量private readonly int distvertical和测试中水平写入的文本方法SameLine要求距离垂直值相等

命名空间iText.Kernel.Pdf.Canvas.Parser.Listener{ 内部类TextChunkLocationDefaultImp:ITextChunkLocation{ ... ///方向单位向量的垂直距离,即未旋转坐标系中的Y位置。 /// /// ///方向单位向量的垂直距离,即未旋转坐标系中的Y位置。 ///我们四舍五入到最接近的整数来处理比较浮点数的模糊性。 /// 私有只读int; ... ///要比较的位置 ///如果此位置与另一个位置在同一条线上,则为true 公共虚拟bool SameLineITextChunkLocation@as{ ... float dist垂直度diff=distvertical-@as.distvertical; 如果dist垂直度diff==0{ 返回true; } ... } ... } } 实际上,如果比较的文本块中有一个长度为零,则向下的SameLine允许有一个小的偏差。显然,长度为零的文本块有时用于变音标记,而这些标记有时应用于不同的高度。不过,在您的示例文件中,这并不重要

如何修复它 如上所述,问题是由于TextChunkLocationDefaultImp.SameLine的行为造成的。因此,我们必须更改此行为。不过,通常我们不想更改iText类本身的代码

幸运的是,LocationTextExtractionStrategy有一个构造函数,允许注入ITextChunkLocationStrategy实现,即ITextChunkLocation实例的工厂对象

因此,对于我们的任务,我们必须编写一个不那么严格的替代ITextChunkLocation实现,以及一个生成ITe实例的ITextChunkLocationStrategy实现 xtChunkLocation实现

不幸的是,TextChunkLocationDefaultImp是iText的内部变量,并且有许多私有变量。因此,我们不能简单地从它派生实现,而是必须将它作为一个整体进行复制和粘贴,并将更改应用于该副本

因此,

类LaxTextChunkLocationStrategy:LocationTextExtractionStrategy.ITextChunkLocationStrategy { 公共场所选址策略 { } 公共虚拟ITextChunkLocation CreateLocation TextRenderInfo renderInfo,线段基线 { 返回新的TextChunkLocationLaxImpbaseline.GetStartPoint、baseline.GetEndPoint、renderInfo.GetSingleSpaceWidth; } } 类TextChunkLocationLaxImp:ITextChunkLocation { 私有常量浮点变音符号允许的垂直偏差=2; 私有只读向量定位; 专用只读向量结束位置; 私有只读向量方向向量; 私有只读int方向大小; 私有只读int; 私有只读浮点启动; 私有只读浮点数; 私有只读浮点字符空间宽度; public TextChunkLocation LaximpVector startLocation、Vector endLocation、float charSpaceWidth { this.startolocation=startolocation; this.endLocation=endLocation; this.charSpaceWidth=charSpaceWidth; 向量OVERECTR=结束位置。位置; 如果oVector.Length==0 { oVector=新向量1,0,0; } 方向向量=OVERECTOR.规格化; OrientationMagnite=intMath.Atan2orientationVector.GetVector.I2,orientationVector.GetVector.I1*1000; 向量原点=新向量0,0,1; DistVertical=intstartLocation.Subtractorigin.CrossOriginationVector.GetVector.I3; distParallelStart=orientationVector.dotstarlocation; distParallelEnd=方向向量.DotendLocation; } 公共虚拟国际定位 { 返回方向大小; } 公共虚拟整数域 { 返回垂直; } 公共虚拟浮点数启动 { 返回并启动; } 公共虚拟浮点数 { 返回端; } 公共虚拟矢量定位 { 返回定位; } 公共虚拟向量GetEndLocation { 返回端定位; } 公共虚拟浮点GetCharSpaceWidth { 返回字符空间宽度; } 公共虚拟bool SameLineITextChunkLocation@as { 如果方向重要性!=@as.orientationmagnity { 返回false; } int dist垂直度diff=distvertical-@as.distvertical; 如果数学横坐标垂直度差<2 { 返回true; } LineSegment mySegment=新的LineSegment位置、结束位置; 线段otherSegment=新建LineSegment@as.GetStartLocation,@as.GetEndLocation;
return Math.absdist垂直度diff请共享有问题的PDF。很可能PDF中的垂直位置有一个小的变化,其中提取的文本有额外的换行符。Hi@mkl从我的角度看,看起来没有,但可能有1个像素。我在这里上传了文件,我不得不过滤掉机密数据。对于vertical位置,你应该检查页面内容流,而不是查看呈现的页面。欢迎来到地狱。幸运的是,mkl可能会给你一些启示。旋转、大小、cropbox、用户单位、iTextractionStrategy…上帝不。简言之:你看到的不是你得到的!是的,这一切都很复杂,我真的希望@mkl能如此我来说说这个例子。请分享有问题的PDF。最有可能的是,在PDF的垂直位置有一个小的变化,其中提取的文本有额外的换行符。您好@mkl从我看来,它看起来没有,但它可能像1个像素。我在这里上传了文件,我不得不过滤掉机密数据。对于垂直位置,您可以应该检查页面内容流,而不是查看呈现的页面。欢迎来到地狱。幸运的是,mkl可能会给你一些启示。旋转、大小、cropbox、用户单位、iTextractionStrategy…上帝不。简言之:你看到的不是你得到的!是的,这一切都很复杂,我真的希望@mkl能对此有所启示s案例。谢谢你的详细解释,这很好!我可以问你如何验证pdf以了解行的准确位置吗?@thekguy我可以问你如何验证pdf以了解行的准确位置吗?-请参阅新的部分如何检查pdf以了解我在答案中编辑的行的准确位置。谢谢你他详细解释说,这很好!我可以问一下你是如何解读pdf以了解行的确切位置的吗?@thekguy我可以问一下你是如何解读p的吗 df是否知道行的确切位置?-请参阅新的部分如何检查pdf以了解我在答案中编辑的行的确切位置。
item[tab]item[tab]item[tab]item[tab]item
item[tab]item[tab]item[tab]
item[tab]item
item[tab]item[tab]item[tab]item[tab]item