Извлечь портфолио PDF с большим количеством PDF в нем

У меня есть портфолио PDF с папками, подпапками и файлами. Мне нужно извлечь ту же структуру, используя iText в Java. Я не могу извлечь портфолио 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 равно нулю.

1 ответ

Проблема в том, что ваш код (который может быть основан на ответе, который я дал) предполагает, что (Каталог) -> Имена -> 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

Это предположение неверно. (Каталог) -> Имена -> EmbeddedFiles является корнем так называемого дерева имен, и в качестве дерева оно может иметь детей, у которых снова могут быть собственные дети и т. Д., Что в конечном итоге приводит к конечному узлу, содержащему массив имен с записями Filespec.

Если у вас есть PDF с очень небольшим количеством вложений, обычно его дерево имен EmbeddedFiles несколько сжато, его корень также является единственным листовым узлом, и это ситуация, которую понимает ваш код и код из моего предыдущего ответа.

Таким образом, ваш код должен быть улучшен для повторения здесь, не только для поиска Имен во EmbeddedFiles, но и для Детей, а внутри них также не только для Имен, но также для Детей и т. Д. И т. Д.

Другие вопросы по тегам