当前位置: 首页 > 知识库问答 >
问题:

使用iText“重新分页”PDF

韦知
2023-03-14

免责声明

我使用的是iText5。我知道这通常不受欢迎(相对于使用iText7),但我正在使用大量使用iText5的遗留代码,升级不在我的控制范围内。

    null

进展/办法:

我扩展了SimpleTextExtractionStrategy以生成包含字体信息(大小和系列、粗体或斜体等)以及位置信息(相对于绝对坐标系,原点位于输入PDF第一页的左上角)的XML。

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

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

这组需求还应该包括带有表格的PDF。我最初计划为表PDF实现一个不同的模块,该模块遵循相同的接口,因为这些PDF与从RTF生成的PDF是分开生成和使用的,而且iText内置了相对较强的表功能。

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

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

共有1个答案

米子轩
2023-03-14

我前一段时间解决了这个问题,但我想我会张贴我的解决方案。我肯定这不是最有效的解决方案,但它对我的目的很有效。请注意,这将重新分页PDF,如问题中所述,只包含文本。表PDF单独处理。

基本过程如下:

  1. 使用自定义TextExtractionStrategy提取包含有关输入PDF中所有文本的上升线和下降线信息的XML,以及它最初出现在哪个页面上。
  2. 给定问题中描述的页长要求(第一页=输入值,后续=标准长度,最后一页=适合内容)和关于文本位置的XML信息,确定输出PDF的每一页适合什么内容。创建每个输入页面需要裁剪的位置(顶部和底部,请注意每个输入页面可能被裁剪不止一次)的映射,以及在最终输出中需要“连接”哪些被裁剪的页面的映射。
  3. 将输入的PDF逐页复制到中间临时PDF(使用pdfcopier)。如果一个输入页面必须被裁剪不止一次(例如:第一个2英寸的输入页面1=第1页输出,下一个6英寸的输入页面1=第2页输出,最后0.5英寸的输入页面1=第3页输出的顶部),请确保复制该页面的次数适当(每次裁剪1次)。
  4. 适当裁剪中间复制PDF的每一页。这是通过修改mediabox和/或cropbox来实现的。
  5. 将适当裁剪的页面连接到最终输出PDF的页面中。我使用pdfwriter首先创建适当高度的新页,然后使用contentbyte.addtemplate(inputCroppedPage,0,bottomOfLastAddedCroppedPage).
  6. 在输出PDF页字节内容的适当位置html" target="_blank">添加每个适当裁剪的页

步骤1中提到的TextExtractionStrategy就是受这个答案的启发。实际上,我使用system.XML.linq来创建XML文档,而不是将字符串连接起来形成HTML,并且忽略了任何字体信息,只存储了关于文本在页面中的位置的信息(您将看到这些信息在链接的答案中可用,只是没有写入最终的HTML中)。

 类似资料:
  • 问题内容: 我正在使用 itext pdf 库。谁能知道我如何在现有的pdf中移动页面? 实际上,我想 在文件开头移动最后几页。 它类似于下面的内容,但我不知道它是如何工作的。 谁能详细解释一下? 问题答案: 该方法在我的书的第6章中进行了说明(请参见第164页)。在代码片段6.3和6.11的上下文中,它用于减少由或消耗的正在读取的页面数。但是,它也可以用于重新排序页面。首先让我解释一下语法。 该

  • 问题内容: 我想使用itext生成pdf。我会在某些时候添加内容以进行分页。我需要插入几个单独的conenidos依赖源,所以我要求用户在单独的页面上插入。有任何想法吗??? 问题答案: 调用告诉iText将后续对象放置在新页面上。仅当您放置下一个对象时,才会真正创建新页面。另外,仅在当前页面不为空白时创建一个新页面;否则,仅创建一个新页面。否则,它将被忽略;您可以用来克服这一点。 请参见下面的链

  • 我想用iText生成一个pdf。我会在某个时候添加内容以进行分页。我需要插入几个单独的conenidos依赖源,所以我要求用户在单独的页面上这样做。有什么想法吗???

  • 问题内容: 我正在尝试使用具有以下代码的iText 7创建PDF文档,并且生成时,我的PDF文档内容在同一页面中重叠(即,在第1页中)。 我看到了 document.newPage(); iText 7中缺少该方法。如何在itext 7中不使用pdfDocumet.copyPages(…)或PDFmerger将页面添加到我的PDF文档中。 问题答案: 在iText 7中,该方法已成为区域中断的特殊

  • 因为我事先不知道页码,所以我最初的想法是通过多次传递创建PDF,如“iText in Action”第6章所述。然而,据我所知,这是行不通的,因为一旦创建了现有的文本块,PDFStamper就无法编辑它们。我的第二个想法是创建两次文档。第一次,我将创建文档,并简单地对文本和页码中的引用位置进行hashmap。第二次,我将使用它们来生成引用。 有没有更好的办法做到这一点?