【问题标题】:OpenPDF/iText corrupt documentsOpenPDF/iText 损坏的文档
【发布时间】:2019-03-22 09:19:11
【问题描述】:

我一直在尝试在 Scala 中重新实现 OpenPDF 1.2.4 和 1.2.11 中的连接示例:

def mergePdfs(docs: Seq[Array[Byte]]): Array[Byte] = {
    log.debug(s"merging ${docs.size} PDFs")
    val output = new ByteArrayOutputStream()
    val document = new Document()
    val copy = new PdfCopy(document, output)
    getPageSize(docs.headOption) foreach document.setPageSize
    document.open()
    docs foreach { doc =>
      val reader = new PdfReader(doc)
      1 to reader.getNumberOfPages foreach { pageNum =>
        copy.addPage(copy.getImportedPage(reader, pageNum))
      }
    }
    document.close()
    output.toByteArray
  }

Here Here 是一个示例输出文档。我从this 的两个副本和this 的三个副本生成它。

我看到两个问题:

- 文档已损坏(仅在 FireFox 中打开),部分原因是标题和第一个对象之间有一行杂物。删除有问题的行并不能修复客户端代码中的文档错误,感谢@mkl!

  • 某些页面(通常是一个,但它是不确定的)显示为空白。没有我见过的模式。此外,每个页面的文本在文件中出现两次。例如在上面的例子中:
$ strings out.pdf | grep "A Simple PDF File" | wc -l | tr -d ' '
6

在一种情况下,我使用 vim 删除了第一个内容流,这导致文本出现在第一页上。

我是否以某种方式滥用了 API?

【问题讨论】:

  • 乍一看,代码看起来没问题(尽管我不明白pageSize.foreach(document.setPageSize) 可能会做什么有意义)。难道你在这个方法之外把这里返回的字节数组当作文本?请分享一个示例问题 PDF 以供分析。
  • 很高兴澄清! pageSize 是一个 Maybe monad(在 Scala 中称为 Option),它是零个或一个元素的集合。因此,如果有,它会获取第一个源文档的页面大小,然后如果有,它会设置目标文档的页面。 PDF 即将推出。
  • 添加了输入和输出示例。感谢您检查我是否正确处理输入和输出!就我而言,我所做的只是从 CLI 中的每个路径调用 Files.getAllBytes,然后使用生成的字节数组调用 Files.write。这种错误潜入的空间不大。
  • 这是关于 iText 还是关于 OpenPDF 的问题?这不能是关于两者的问题......
  • @ILikeFood 您的新示例输出文档链接返回与旧链接相同的文件。

标签: scala itext openpdf


【解决方案1】:

结果文件的前 17465 个字节是代码的实际结果(“两个副本,然后三个副本”)。 31181 字节文件的剩余字节由其他 PDF 的片段组成。

在评论中,您说您“使用生成的字节数组调用 Files.write。” 您使用的是哪个OpenOptions?可能是CREATE,但不是TRUNCATE_EXISTING

【讨论】:

  • 经典?。使用TRUNCATE_EXISTING 解决了文件损坏问题,但我仍然得到空白页 - 与我们通过生产代码路径执行此操作时所看到的一致(问题已更新)。期待与 iText 和我一起度过一个愉快的漫长调试日期。
猜你喜欢
  • 2021-09-13
  • 2014-03-24
  • 2021-06-20
  • 2011-12-15
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多