首页 文章

使用iText“重新分页”PDF

提问于
浏览
0

Disclaimer:

我正在使用iText 5.我知道这通常是不赞成的(与使用iText 7相比),但我正在处理使用iText 5的大量遗留代码,升级不受我的控制 .

Requirements:

  • A "simple" PDF / A作为输入接收(仅文本,这些是从RTF生成的),以及与所需的第一页长度(以英寸为单位)对应的浮点值 .

  • 必须输出与输入PDF相同的PDF / A,除了它的分页如下:第一页长度=输入值;每个后续(不是第一个或最后一个)页面将填充标准页面长度;最后一页将被截断在距离页面底部最近的内容之下的恒定点数 . 请注意,输入和输出宽度将是相同且恒定的 .

Progress / Approach:

我扩展了 SimpleTextExtractionStrategy 以生成包含字体信息(大小和族,粗体或斜体等)的XML以及位置信息(相对于输入的第一页左上角的原点的绝对坐标系统PDF)对于从输入PDF中提取的每个"span"文本 .

然后,我逐页生成一个新的PDF(根据上面列出的要求,每个页面都是所需的长度),根据每个新页面的边界使用LINQ过滤提取的XML信息,并在适当的位置添加适当格式的文本使用 ColumnText.ShowTextAligned(...) .

Problem:

上面概述的方法很好 . 它生成具有所需页面结构的PDF,但某些信息在翻译时丢失,即彩色文本和带下划线的文本 . 虽然不应在这些PDF中看到彩色文本,但绝对必须检测带下划线的文本 .

这组要求还应包括带表格的PDF . 我最初计划实现一个不同的模块,该模块遵循表格PDF的相同界面,因为它们是从RTF生成的PDF中单独生成和使用的,而且iText内置了相对强大的表格功能 .

上面提到的两个问题,再加上我所描述的方法源于重用现有代码的尝试,这让我相信完全不同的方法可能是必要的,或者至少要好得多 . 在我看来,应该有一种方法来捕获内容字节信息并根据需要剪辑它以“重新分页”输入PDF,只担心移动沿页面边界的内容 .

基本上,我正在寻找(基于iText)推荐更好的方法 . 伪代码类型的答案或只是对可能有用的类/接口的建议是可接受的 . 虽然将文本和表格放在一起会很好,但任何与一个或另一个相关的建议也会受到赞赏 . 我已经仔细阅读了iText网站上的大部分可用文档和其他SO问题,但还没有找到我正在寻找的内容 .

请注意,此问题中不包含任何代码,因为我正在寻找与我尝试过的完全不同的高级方法 .

Edit:

我以前没有注意到它,但是我重用字体的方式(类似于this)导致了一些意想不到的(但是记录在案)这样的行为 . 似乎我需要避免在文本级别提取重新分页的信息,因为很难确保输入和输出之间字体的连续性 .

1 回答

  • 0

    我刚才解决了这个问题,但我想我会发布我的解决方案 . 我_438197不是最有效的解决方案,但它适用于我的目的 . 请注意,这将按照包含 text only 的问题中所述重新分页PDF . 表PDF是单独处理的 .

    基本过程是这样的:

    • 使用自定义 TextExtractionStrategy 提取XML,其中包含有关输入PDF中所有文本的上升和下降行的信息,以及它最初显示在哪个页面上 .

    • 给定问题中描述的页面长度要求(第一页=输入值,后续=标准长度,最后一页=适合内容)和有关文本位置的XML信息,确定哪些内容适合输出PDF的每一页 . 创建一个 Map ,其中每个输入页面都需要被裁剪(顶部和底部,请注意每个输入页面可能被裁剪多次),以及在最终输出中需要裁剪页面的 Map "concatenated" .

    • 将输入PDF逐页复制到中间临时PDF(使用 PdfCopier ) . 如果输入页面必须多次裁剪(例如:前2英寸输入页面1 =页面1输出,接下来6英寸输入页面1 =页面2输出,最后0.5英寸输入页面1 =页面3输出顶部),确保复制适当的次数(每次作物1次) .

    • 适当地裁剪中间复制PDF的每个页面 . 这是通过修改 MediaBox 和/或 CropBox 来完成的 .

    • 将适当的裁剪页面连接到最终输出PDF的页面 . 我使用 PdfWriter 首先创建适当高度的新页面,然后使用 contentByte.AddTemplate(inputCroppedPage, 0, bottomOfLastAddedCroppedPage) 将每个适当的裁剪页面添加到输出PDF页面的字节内容中的适当位置 .

    对于那些设法阅读并理解所有这些内容的人,恭喜你 . 对于其他任何人,如果您感到困惑,请告诉我您的意见 . 上面描述的解决方案有点扭曲,难以用语言表达 . 虽然这里发布的代码太多了(而且我无权在GitHub或类似代码上共享代码),但我很乐意回答任何有助于其他人实现类似内容的问题 .

    步骤1中提到的 TextExtractionStrategy 受到this answer的启发 . 本质上,我使用 System.Xml.Linq 创建XML文档而不是连接字符串以形成HTML,我忽略了任何字体信息,只存储有关文本在页面中的位置的信息(您将'll see that this information is available in the linked answer, just isn'写入最终的HTML) .

相关问题