2016-02-23 3 views
-1

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

+0

Пожалуйста, поделитесь PDF-файлом, чтобы воспроизвести проблему. – mkl

+0

Thankx для ответа .. найдите ниже ссылку для файла PDF [link] (https://onedrive.live.com/embed?cid=464EC333E3DD6FA5&resid=464EC333E3DD6FA5%21107&authkey=AEF0aYu1yy6iVXQ) –

ответ

3

Вопрос заключается в том, что ваш код (который может быть основан на this answer я дал) предполагает, что (каталог) ->Имена ->EmbeddedFiles немедленно содержит Имена массив с специф_файлов записей в :

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 имя дерева несколько прессованные, его корень, являющийся также его единственным листовым узлом, и это ситуация ваш код и код из my former answer понимает.

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

+0

Thankx для ответа .. может u пожалуйста, исправьте мою логику в коде, чтобы рекурсивно проверять массив имен. Поскольку я не могу этого сделать. –

Смежные вопросы