2015-03-31 21 views
6

Tôi có một mẫu pdf được thực hiện và tôi đang cố gắng sử dụng pdfBox để điền vào mẫu và in tài liệu. Tôi nhận được nó làm việc tuyệt vời cho 1 công việc in trang nhưng tôi đã phải cố gắng và sửa đổi cho nhiều trang. Về cơ bản nó là một hình thức với thông tin cơ bản lên trên và một danh sách các nội dung. Vâng, nếu các nội dung lớn hơn những gì các hình thức có chỗ cho tôi phải làm cho nó một tài liệu nhiều trang. Tôi kết thúc với một tài liệu với một trang đẹp và sau đó tất cả các trang còn lại là mẫu trống. Tôi đang làm gì sai?Java pdfBox: Điền vào mẫu pdf, thêm nó vào pddocument, và lặp lại

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 

Trả lời

9

Có hai vấn đề chính trong bạn mã:

  • Yếu tố AcroForm của một PDF là một đối tượng mức độ tài liệu. Bạn chỉ sao chép trang mẫu được điền vào finalDoc. Do đó, các trường biểu mẫu được thêm vào finalDoc chỉ dưới dạng chú thích của trang tương ứng nhưng chúng không được thêm vào AcroForm của finalDoc.

    Điều này không rõ ràng trong Adobe Reader nhưng các dịch vụ điền biểu mẫu thường xác định các trường có sẵn từ mục nhập AcroForm cấp tài liệu và không tìm kiếm các trang cho các trường biểu mẫu bổ sung.

  • Trình hiển thị thực tế: Bạn thêm các trường có tên giống hệt với PDF. Nhưng các biểu mẫu PDF là các thực thể trên toàn tài liệu. I E. chỉ có thể có một thực thể trường duy nhất có tên đã cho trong tệp PDF. (Thực thể trường này có thể có nhiều trực quan hóa các tiện ích con nhưng điều này đòi hỏi bạn phải xây dựng một đối tượng trường duy nhất với nhiều tiện ích con. Hơn nữa, các tiện ích này được mong đợi hiển thị cùng một giá trị không phải là thứ bạn muốn ...)

    Vì vậy, bạn phải đổi tên các trường duy nhất trước khi thêm chúng vào finalDoc.

Dưới đây là một simplified example mà hoạt động trên một mẫu với chỉ có một trường "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")); 
} 

Như bạn thấy tất cả các trường được đổi tên trước khi chúng được thêm vào finalForm:

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

và chúng được thu thập trong danh sách fields mà cuối cùng được thêm vào finalForm AcroForm:

fields.add(field); 
} 
... 
finalForm.setFields(fields); 
Các vấn đề liên quan