2016-03-23 9 views
1

Ich arbeite an Java-Projekt hinzugefügt und ich habe folgende Situation:PDFBox nach PDAnnotationLinks Dateigröße wird zweimal erhöht

  1. Ich habe PDF-Datei mit Apache FOP erzeugte bestehende. Im Inneren befinden sich Lesezeichen, die mit Ich erhalte:

    Map<String, PDAction> actionsMap = new HashMap<String, PDAction>(); 
    PDDocumentOutline bookmarks = doc1.getDocumentCatalog().getDocumentOutline(); 
    PDOutlineItem item = bookmarks.getFirstChild(); 
    while(item != null){ 
        actionsMap.put(item.getTitle(), item.getAction()); 
        item = item.getNextSibling(); 
    } 
    
  2. Ich zweite Datei bin Öffnung (wieder erzeugt FOP) mit PDFBox 2.0.0 und 3 PDAnnotationLinks auf bestimmte Teile des Textes hinzuzufügen. Die Datei ist eine einzelne Seite mit wenigen Diagrammen. Dann füge ich die aus Punkt 1

    PDPage page = (PDPage) diagramDocument.getDocumentCatalog().getPages().get(0); 
    //objCoordinates is retrieved from another class with PDFTextStripper 
    Iterator entries = objCoordinates.entrySet().iterator(); 
    while (entries.hasNext()) { 
        Entry entry = (Entry) entries.next(); 
        String key = (String) entry.getKey(); 
        PDAnnotationLink txtLink = new PDAnnotationLink(); 
        PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary(); 
        borderULine.setWidth(0); 
        txtLink.setBorderStyle(borderULine); 
        PDActionGoTo action = (PDActionGoTo) actionsMap.get(key); 
        txtLink.setAction(action); 
    
        final float[] quads = (float[]) entry.getValue(); 
        PDRectangle rect = new PDRectangle(); 
        rect.setLowerLeftX(quads[0]); 
        rect.setLowerLeftY(quads[5]); 
        rect.setUpperRightX(quads[2]); 
        rect.setUpperRightY(quads[1]); 
        txtLink.setRectangle(rect); 
    
        page.getAnnotations().add(txtLink); 
    } 
    

Nach der zweiten Datei zu speichern, die Links funktionieren, aber die Dateigröße verdoppelt wird. PDF-Version ist 1.6. Die Datei hat bereits den Filter FlateDecode. Ich habe online PDF-Dateien Vergleich (erste Datei und Ergebnisdatei mit Links) versucht, aber das Ergebnis ist, dass die Dateien keinen Unterschied haben. Wenn ich die Dateien mit dem Texteditor öffne, gibt es - Originaldatei - 1 Typ/Seite/Instanz - Ergebnisdatei - 18/Typ/Seiteninstanzen Ich schätze, dass PDFBOX zusätzliche (doppelte?) Informationen hinzufügt.

Wenn jemand auf dieses Problem gestoßen ist, würde ich mich über einen Ratschlag freuen.

Dank

+1

es ohne die Datei schwierig ist, aber mein Gefühl ist, dass, wenn Sie PDActionGoTo action = (PDActionGoTo) actionsMap.get (Schlüssel) zu tun; Sie verweisen auf eine Seite aus der anderen Datei. "Seite ist ein indirekter Verweis auf ein Seitenobjekt" => Sie sollten sicherstellen, dass das Ziel Ihrer Goto-Aktion eine Seite Ihres eigenen Dokuments ist. BTW nur ​​für den Fall, Sie erwähnten "2.0.0", ich hoffe, es ist die veröffentlichte Version und nicht RC3. –

+0

Hi Tilman, Ja, ich benutze die Version 2.0.0, aber das Problem ist wo sonst. Wie Sie richtig sagten, sollte die Aktion "Gehe zu" eine Seite Ihres eigenen Dokuments sein und ich zeige auf die Seite aus einem anderen Dokument ... Danke, dass Sie darauf hingewiesen haben. Ich muss meinen Code überarbeiten und mehr über PDFBOX lesen – micky

+0

Ihre zweite Datei hat nur eine Seite, daher sollte es einfach sein, den PDPage-Parameter des PDPageDestination der goto-Aktion zuzuweisen. action.setDestination (Seite). –

Antwort

1

ich gerade fragen, wie Sie eine Kredit Tilman geben ... :-) Ok, ich habe überarbeitet und vereinfacht den Code, damit ich es hier posten. Hoffe, dass es klar ist,

import java.io.File; 
    import java.util.ArrayList; 
    import java.util.HashMap; 
    import java.util.Iterator; 
    import java.util.List; 
    import java.util.Map; 
    import java.util.Map.Entry; 

    import org.apache.pdfbox.pdmodel.PDDocument; 
    import org.apache.pdfbox.pdmodel.PDPage; 
    import org.apache.pdfbox.pdmodel.common.PDRectangle; 
    import org.apache.pdfbox.pdmodel.interactive.action.PDAction; 
    import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; 
    import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink; 
    import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary; 
    import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline; 
    import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; 
    import org.apache.pdfbox.text.PDFTextStripper; 

    /** 
    * @author micky 
    * 
    * The class merges PDF files 
    * - one file with item details info 
    * - one or more files with items diagrams 
    * 
    * Purpose is to merge diagram files into item details file and create links 
    * from the items in diagrams to item details 
    */ 
    public class PDFReportHyperlinks { 

     public static void main(String[] args){ 

      PDDocument reportDocument = null; 
      try { 

       String reportFileName = "D:/ItemsDetails.pdf"; 

       Map<String, PDAction> actionsMap = new HashMap<String, PDAction>(); 
       reportDocument = PDDocument.load(new File(reportFileName)); 

       // Get the bookmarks i.e. existing GoTo actions 
       PDDocumentOutline bookmarks = reportDocument.getDocumentCatalog().getDocumentOutline(); 
       PDOutlineItem item = bookmarks.getFirstChild(); 
       while(item != null){ 
        actionsMap.put(item.getTitle(), item.getAction()); 
        item = item.getNextSibling(); 
       } 

       // Diagram files, they have single page 
       List diagamFiles = new ArrayList<String>() {{ 
         add("D:/Diagram_1.pdf"); 
         add("D:/Diagram_2.pdf"); 
         add("D:/Diagram_3.pdf"); 
       }}; 

       Iterator diagramsIt = diagamFiles.iterator(); 
       while (diagramsIt.hasNext()) { 
        String diagramName = (String) diagramsIt.next(); 

        //--<Import diagram>--------------------------------- 
        PDDocument sourceDocument = PDDocument.load(new File(diagramName)); 
        PDPage pp = (PDPage) sourceDocument .getDocumentCatalog().getPages().get(0); 
        PDPage page = reportDocument.importPage(pp); 

        //--<Create links from diagrams to objects>--------------------------------- 

        // TextStripper is separate class extending PDFTextStripper 
        // It is searching for items names and returning Map with their coordinates 
        TextStripper stripper = new TextStripper(sourceDocument, 
          new ArrayList<String>() {{ 
           add("Item1_Name"); 
           add("Item2_Name"); 
           add("Item3_Name"); 
           add("Item4_Name"); 
           add("Item5_Name"); 
          }}); 

        Map<String, float[]> objCoordinates = stripper.getObjCoordinates(); 

        Iterator entries = objCoordinates.entrySet().iterator(); 
        while (entries.hasNext()) { 
         Entry entry = (Entry) entries.next(); 
         String key = (String) entry.getKey(); 

         PDAnnotationLink txtLink = new PDAnnotationLink(); 
         PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary(); 
         borderULine.setWidth(0); 
         txtLink.setBorderStyle(borderULine); 
         PDActionGoTo action = (PDActionGoTo) actionsMap.get(key); 
         txtLink.setAction(action); 

         final float[] quads = (float[]) entry.getValue(); 
         PDRectangle rect = new PDRectangle(); 
         rect.setLowerLeftX(quads[0]); 
         rect.setLowerLeftY(quads[5]); 
         rect.setUpperRightX(quads[2]); 
         rect.setUpperRightY(quads[1]); 
         txtLink.setRectangle(rect); 

         page.getAnnotations().add(txtLink); 
        } 

        //--<Create bookmarks for new pages (diagrams)>--------------------------------- 
        PDOutlineItem menuItem = new PDOutlineItem(); 
        menuItem.setTitle(diagramName); 
        menuItem.setDestination(page); 
        bookmarks.addLast(menuItem); 
        menuItem.openNode(); 
        bookmarks.openNode(); 

       } 

       reportDocument.save(new File(reportFileName)); 
       reportDocument.close(); 

       // Alternative merging documents example not feasible in this case 
       //PDFMergerUtility ut = new PDFMergerUtility(); 
       //ut.addSource(reportFileName); 
       //diagramsIt = diagamFiles.iterator(); 
       //while (diagramsIt.hasNext()) { 
       // String diagramName = (String) diagramsIt.next(); 
       // ut.addSource(diagramName); 
       // } 
       //ut.setDestinationFileName(reportFileName); 
       //ut.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()); 

       System.out.println("COMPLETED"); 

      } catch (Exception e) { 
       System.out.println(e); 
      } finally { 
       try { 
        reportDocument.close(); 
       } catch (Exception e) { 
        System.out.println(e); 
       } 
      } 
     } 
    } 
Verwandte Themen