使用 PDFMergerUtility 合并两个 pdf 文档抛出:IOException("Page tree root must be a dictionary")

Merging two pdf documents with PDFMergerUtility throws: IOException("Page tree root must be a dictionary")

我有一个 spring 引导应用程序,我正在尝试合并两个 pdf 文件。一个是我从另一个服务获取的字节数组,另一个是我在本地的资源文件中:/static/documents/my-file.pdf。这是我如何从资源文件中获取字节数组的代码:

public static byte[] getMyPdfContentForLocale(final Locale locale) {
    byte[] result = new byte[0];
    try {
        final File myFile = new ClassPathResource(TEMPLATES.get(locale)).getFile();
        final Path filePath = Paths.get(myFile.getPath());
        result = Files.readAllBytes(filePath);
    } catch (IOException e) {
        LOGGER.error(format("Failed to get document for local %s", locale), e);
    }
    return result;
}

我正在获取文件并获取字节数组。后来我试图用下面的代码合并这两个文件:

PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
pdfMergerUtility.addSource(new ByteArrayInputStream(offerDocument));
pdfMergerUtility.addSource(new ByteArrayInputStream(merkblattDocument));
ByteArrayOutputStream os = new ByteArrayOutputStream();
pdfMergerUtility.setDestinationStream(os);
pdfMergerUtility.mergeDocuments(null);
os.toByteArray();

但不幸的是它抛出一个错误:

throw new IOException("Page tree root must be a dictionary");

我已经检查过,它在抛出之前进行了验证:

if (!(root.getDictionaryObject(COSName.PAGES) instanceof COSDictionary))
    {
        throw new IOException("Page tree root must be a dictionary");
    }

而且我真的不知道这是什么意思以及如何解决它。 最奇怪的是我创建了全新的项目并尝试使用相同的代码来合并两个文档(相同的文档)并且它有效!

另外我试过的是:

  1. 如果可以就更改spring引导版本
  2. 像这样设置 mergeDocuments 方法:pdfMergerUtility.mergeDocuments(setupMainMemoryOnly())
  3. 像这样设置 mergeDocuments 方法:pdfMergerUtility.mergeDocuments(setupTempFileOnly())
  4. 使用不同的方法获取字节,而不是使用 java.nio:
  5. 中的文件
  6. 并且还在另一个线程中执行了这个
  7. 仅合并本地存储的文件(在资源中)
  8. 合并我从其他服务获取的文件 - 顺便说一句,这很有效,这就是我确定他没问题的原因

有人可以帮忙吗?

Tilman Hausherr 所说的问题在于您可以在 pom 文件中找到的资源过滤。如果您遇到不允许修改此内容的情况,那么此方法将帮助您:

final String path = new 
ClassPathResource(TEMPLATES.get(locale)).getFile().getAbsolutePath();
final File file = new File(path);
final Path filePath = Paths.get(file.getPath());
result = Files.readAllBytes(filePath);

然后将字节传递给 pdfMergerUtility 对象(或者甚至是整个文件而不是字节列表)。