提取具有大量pdf的组合pdf

时间:2016-02-23 09:54:11

标签: java pdf itextsharp itext portfolio

我有一个包含文件夹,子文件夹和文件的PDF文件夹。我需要在java中使用iText提取相同的结构。我无法提取大量没有pdfs的组合pdf。小编没有pdfs工作正常。

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

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变量的代码值中,变量为空。

1 个答案:

答案 0 :(得分:3)

问题是您的代码(可能基于我提供的this answer)假定(目录) - &gt; 名称 - &gt; EmbeddedFiles 会立即包含带 Filespec 条目的名称数组:

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

这个假设是错误的。 (目录) - &gt; 名称 - &gt; EmbeddedFiles 是所谓的名称树的根,并且作为树,它可能有孩子,这可能再次孩子他们自己等只会最终导致包含带 Filespec 条目的名称数组的叶节点。

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

因此,您的代码需要加强才能在此处进行递归,不仅要在 EmbeddedFiles 中查找名称,还要在孩子中查找,并在其中查找此外,不仅要寻找名称,还要寻找孩子等等。