2015-03-31 14 views
6

Ho creato un modulo PDF e sto cercando di utilizzare pdfBox per compilare il modulo e stampare il documento. Ho funzionato benissimo per lavori di stampa di 1 pagina, ma ho dovuto provare e modificare per più pagine. Fondamentalmente è un modulo con informazioni di base in alto e un elenco di contenuti. Bene, se il contenuto è più grande di quello che il modulo ha spazio, devo renderlo un documento di più pagine. Finisco con un documento con una bella pagina e poi tutte le pagine rimanenti sono il modello vuoto. Che cosa sto facendo di sbagliato?Java pdfBox: compilare il modulo pdf, aggiungerlo a pddocument e ripetere

PDDocument finalDoc = new PDDocument(); 
File template = new File("path/to/template.pdf"); 

//Declare basic info to be put on every page 
String name = "John Smith"; 
String phoneNum = "555-555-5555"; 
//Get list of contents for each page 
List<List<Map<String, String>>> pageContents = methodThatReturnsMyInfo(); 

for (List<Map<String, String>> content : pageContents) { 
    PDDocument doc = new PDDocument().load(template); 
    PDDocumentCatlog docCatalog = doc.getDocumentCatalog(); 
    PDAcroForm acroForm = docCatalog.getAcroForm(); 

    acroForm.getField("name").setValue(name); 
    acroForm.getField("phoneNum").setValue(phoneNum); 

    for (int i=0; i<content.size(); i++) { 
     acroForm.getField("qty"+i).setValue(content.get(i).get("qty")); 
     acroForm.getField("desc"+i).setValue(content.get(i).get("desc")); 
    } 

    List<PDPage> pages = docCatalog.getAllPages(); 
    finalDoc.addPage(pages.get(0)); 
} 

//Then prints/saves finalDoc 

risposta

9

ci sono due grandi questioni in voi codice:

  • L'elemento AcroForm di un PDF è un oggetto a livello di documento. Copi solo la pagina del modello compilato in finalDoc. Pertanto, i campi modulo vengono aggiunti a finalDoc solo come annotazioni della rispettiva pagina ma non vengono aggiunti all'AcroForm di finalDoc.

    Questo non è evidente in Adobe Reader, ma i servizi di compilazione dei moduli spesso identificano i campi disponibili dalla voce AcroForm a livello di documento e non cercano nelle pagine campi aggiuntivi.

  • Il fermo di presentazione effettivo: Aggiungere campi con nomi identici al PDF. Ma i moduli PDF sono entità a livello di documento. Cioè ci può essere solo una singola entità campo con un nome specifico in un PDF. (Questa entità di campo può avere più visualizzazioni o widget, ma questo richiede che tu costruisca un singolo oggetto di campo con più widget secondari.Inoltre questi widget dovrebbero visualizzare lo stesso valore che non è quello che vuoi ...)

    Pertanto, è necessario rinominare i campi in modo univoco prima di aggiungerli allo finalDoc.

Ecco un simplified example che lavora su un modello con un solo campo "SampleField":

byte[] template = generateSimpleTemplate(); 
Files.write(new File(RESULT_FOLDER, "template.pdf").toPath(), template); 

try ( PDDocument finalDoc = new PDDocument();) 
{ 
    List<PDField> fields = new ArrayList<PDField>(); 
    int i = 0; 

    for (String value : new String[]{"eins", "zwei"}) 
    { 
     PDDocument doc = new PDDocument().load(new ByteArrayInputStream(template)); 
     PDDocumentCatalog docCatalog = doc.getDocumentCatalog(); 
     PDAcroForm acroForm = docCatalog.getAcroForm(); 
     PDField field = acroForm.getField("SampleField"); 
     field.setValue(value); 
     field.setPartialName("SampleField" + i++); 
     List<PDPage> pages = docCatalog.getAllPages(); 
     finalDoc.addPage(pages.get(0)); 
     fields.add(field); 
    } 

    PDAcroForm finalForm = new PDAcroForm(finalDoc); 
    finalDoc.getDocumentCatalog().setAcroForm(finalForm); 
    finalForm.setFields(fields); 

    finalDoc.save(new File(RESULT_FOLDER, "form-two-templates.pdf")); 
} 

Come si vede tutti i campi vengono rinominati prima di essere aggiunti alla finalForm:

field.setPartialName("SampleField" + i++); 

e sono raccolti nell'elenco fields che infine viene aggiunto al finalForm AcroForm:

fields.add(field); 
} 
... 
finalForm.setFields(fields);