【问题标题】:Extract portfolio pdf with large no of pdfs in it提取包含大量 pdf 的投资组合 pdf
【发布时间】:2016-02-23 23:49:43
【问题描述】:

我有一个包含文件夹、子文件夹和文件的投资组合 PDF。我需要在 java 中使用 iText 提取相同的结构。我无法提取其中包含大量 pdf 的投资组合 pdf。使用少量的 pdf 文件可以正常工作。

请找到我正在使用的代码。

public void extractPortfolio(String src) {
     PdfReader reader = new PdfReader(src);
    PdfDictionary root = reader.getCatalog();

    PdfDictionary names = root.getAsDict(PdfName.NAMES);
    System.out.println("****names names *********" + names.getKeys().toString());
    PdfDictionary embedded = names.getAsDict(PdfName.EMBEDDEDFILES);
    System.out.println("####embedded embedded ########" + embedded.toString());

    PdfArray filespecs =null; 
    filespecs=embedded.getAsArray(PdfName.NAMES);//all pdfs  null in case of large no of pdfs

    for (int i = 0; i < filespecs.size();) {
        try {
            extractAttachment(reader, folders, folder, filespecs.getAsString(i++), filespecs.getAsDict(i++));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
protected  void extractAttachment(PdfReader reader, Map<Integer, File> dirs, File dir, PdfString name, PdfDictionary filespec) throws IOException {
    PRStream stream;
    FileOutputStream fos;
    String filename;
    PdfDictionary refs = filespec.getAsDict(PdfName.EF);

    File dirHere = dir;
    String nameString = name.toUnicodeString();

    if (nameString.startsWith("<")) {

        int closing = nameString.indexOf('>');

        if (closing > 0) {
            int folderId = Integer.parseInt(nameString.substring(1, closing));
            File folderFile = dirs.get(folderId); 
            System.out.println("Folder Fiel>>>"+folderFile.getName());
            if (folderFile != null) {
                dirHere = folderFile;

            }
        }
    }

    for (PdfName key : refs.getKeys()) {
        stream = (PRStream) PdfReader.getPdfObject(refs.getAsIndirectObject(key));

        filename = filespec.getAsString(key).toString();

        fos = new FileOutputStream(new File(dirHere, filename));
        fos.write(PdfReader.getStreamBytes(stream));
        fos.flush();
        fos.close();
    }
}

在 filespecs 变量的代码值中为 null。

【问题讨论】:

  • 请分享有问题的 PDF 以重现问题。
  • 感谢您的回复.. 请在下面找到 PDF 文件的链接 [链接] (onedrive.live.com/…)

标签: java pdf itextsharp itext portfolio


【解决方案1】:

问题是您的代码(可能基于我给出的this answer)假设 (Catalog) -> Names -> EmbeddedFiles 立即包含带有 Filespec 条目的 Names 数组:

PdfDictionary names = root.getAsDict(PdfName.NAMES);
System.out.println("****names names *********" + names.getKeys().toString());
PdfDictionary embedded = names.getAsDict(PdfName.EMBEDDEDFILES);
System.out.println("####embedded embedded ########" + embedded.toString());

PdfArray filespecs =null; 
filespecs=embedded.getAsArray(PdfName.NAMES);//all pdfs  null in case of large no of pdfs

这个假设是错误的。 (Catalog) -> Names -> EmbeddedFiles 是所谓的 Name Tree 的根,并且作为一棵树,它可能有 Kids 又可能有自己的 Kids 等等。最终导致一个包含 Names 数组的叶节点Filespec 条目。

如果您的 PDF 只包含很少的附件,通常它的 EmbeddedFiles 名称树会有些压缩,它的根也是它唯一的叶节点,这就是您的代码和代码的情况来自my former answer了解。

因此,您的代码需要在此处进行递归增强,不仅要在 EmbeddedFiles 中查找 Names,还要在 Kids 中查找Kids,并在其中查找不仅要查找Names,还要查找Kids等。

【讨论】:

  • 感谢您的回复。您能否更正我在代码中的逻辑,以便递归检查名称数组。因为我不能这样做。
猜你喜欢
  • 1970-01-01
  • 2015-10-25
  • 2011-08-20
  • 1970-01-01
  • 2020-01-22
  • 2022-11-18
  • 2017-04-07
  • 2021-08-20
  • 1970-01-01
相关资源
最近更新 更多