這個系列主要記錄一些itext7裏面出現的一些問題,以及網友問的一些問題,主要是自己的真知灼見,如果有錯誤希望大家能指出,感謝大家一如既往的支持。
Doucment與PdfDocument
之前在itext7學習筆記——第3章提到過:Document
是PdfDocument
的高級別表示,在官方api文檔中,描述了以下主要區別(我整理的):
PdfDocument
:直接跟pdf文檔有關係,有頁面大小等屬性,是比較底層的類Document
:是高級的類,可以有一些高級api,例如設置頁面大小、旋轉、增加元素等操作,它本身是不含pdf裏面的具體語法的,它的add一些操作都是通過渲染器(Rendering)來進行操作的,所以我們可以改變渲染器操作來改變一些操作的動作。
添加新的頁面
問題1
在pdf裏面添加的內容的時候,如果您添加的內容超出了一頁的內容的話,itext7會自動另起一頁來開始繪製,那麼是否有方法來在本頁的內容還沒滿的情況下另起一頁來繪製呢?
回答1
答案肯定是可以,有以下兩種方法:
通過addNewPage()方式
PdfDocument
對象擁有以下方法:
- addNewPage():在最後添加一頁,頁面大小爲
PdfDocument
的默認頁面大小。 - addNewPage(int index):在指定位置創建並插入一頁,頁面大小爲
PdfDocument
的默認頁面大小。 - addNewPage(PageSize pageSize):在最後添加一頁,頁面大小爲指定的頁面大小
- addNewPage(int index,PageSize pageSize):在指定位置創建並插入一頁,頁面大小爲指定的頁面大小。
addNewPage的注意事項
- addNewPage()和addNewPage(PageSize pageSize):執行完addNewPage()以後如果添加內容,添加的內容會在哪邊呢?比如以下情況:
doc.add相關操作
PdfDcoument相關操作
——————
PdfDocument.addPage()
——————
doc.add相關操作
PdfDcoument相關操作
假設一開始只有一頁,那麼執行的情況就是,doc添加的內容都會在第一頁上面,但是PdfDocument添加的內容會在兩頁上。
結論:addNewPage後通過doc添加的內容並不會顯示在最新的一頁上
2. addNewPage(int index)和addNewPage(int index,PageSize pageSize):執行完addNewPage(int index)以後如果添加,添加的內容會在哪邊呢?分爲8種情況:
- index超過當前pdf的頁數,也就是index=pdf頁數+1
- 通過Document添加的內容
- 在執行addNewPage(int index)之前
- 在執行addNewPage(int index)之後
- 通過PdfDocument添加的內容
- 在執行addNewPage(int index)之前
- 在執行addNewPage(int index)之後
- 通過Document添加的內容
- index小於當前pdf的頁數
- 通過Document添加的內容:
- 在執行addNewPage(int index)之前
- 在執行addNewPage(int index)之後
- 通過PdfDocument添加的內容:
- 在執行addNewPage(int index)之前
- 在執行addNewPage(int index)之後
- 通過Document添加的內容:
具體情況大家可以試試,很複雜,綜合起來跟第1點一樣,addNewPage後通過doc添加的內容和PdfDocument添加的內容所在頁面並不是一樣的,那問題來了,是否有一種情況是添加一頁後,doc和PdfDocument添加的內容都是在新的一頁上呢?我們來看一下第二種方法。
通過AreaBreakType.NEXT_PAGE方式
在PdfDocument
中有一個方法:add(AreaBreak areaBreak)
,它的作用是停止繪製當前的元素,通常是page。然後看一下AreaBreak
類的描述:它是停止當前的元素並創建一個新的元素,如果沒有申明PageSize
的大小,那麼它創建的元素大小和當前的元素大小一樣。所以我們可以這麼使用來創建新的一頁:
xxxxxx //當前頁面的操作
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
xxxxxx //在新的頁面上操作
是不是很方便!推薦大家使用這種方式來創建新的頁面!
問題2
我們在第4章的時候添加了一個AcroForm表單,那我們是否新創一頁然後再添加表單呢?
回答2
問題1解決了創建新的一頁的問題,那麼開始解決添加新的表單的問題:在一個pdf中,AcroForm只能有一個,它是一個字典,記錄的是每個小部件的名稱,對應每個小部件註釋的對象,所以表單我們是可以再創建的,只需要把表單裏面小部件的名稱和對象註冊到AcroForm中即可(注意每個小部件的名稱唯一就行),如下代碼:
/**
* Created by ASUS on 2017/9/20.
*/
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfButtonFormField;
import com.itextpdf.forms.fields.PdfChoiceFormField;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.forms.fields.PdfTextFormField;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.AreaBreakType;
import com.itextpdf.layout.property.TextAlignment;
import java.io.File;
import java.io.IOException;
public class C04E02_JobApplication2 {
public static final String DEST = "results/chapter04/job_application2.pdf";
public static void main(String args[]) throws IOException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new C04E02_JobApplication2().createPdf(DEST);
}
public void createPdf(String dest) throws IOException {
//Initialize PDF document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PageSize ps = PageSize.A4;
pdf.setDefaultPageSize(ps);
// Initialize document
Document document = new Document(pdf);
C04E02_JobApplication2.addAcroForm(document);
//Close document
document.close();
}
public static void addAcroForm(Document doc) {
Paragraph title = new Paragraph("Application for employment")
.setTextAlignment(TextAlignment.CENTER)
.setFontSize(16);
doc.add(title);
doc.add(new Paragraph("Full name:").setFontSize(12));
doc.add(new Paragraph("Native language: English French German Russian Spanish").setFontSize(12));
doc.add(new Paragraph("Experience in: cooking driving software development").setFontSize(12));
doc.add(new Paragraph("Preferred working shift:").setFontSize(12));
doc.add(new Paragraph("Additional information:").setFontSize(12));
//Add acroform
PdfAcroForm form = PdfAcroForm.getAcroForm(doc.getPdfDocument(), true);
//Create text field
PdfTextFormField nameField = PdfTextFormField.createText(doc.getPdfDocument(),
new Rectangle(99, 753, 425, 15), "name", "");
form.addField(nameField);
//Create radio buttons
PdfButtonFormField group = PdfFormField.createRadioGroup(doc.getPdfDocument(), "language", "");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(130, 728, 15, 15), group, "English");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(200, 728, 15, 15), group, "French");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(260, 728, 15, 15), group, "German");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(330, 728, 15, 15), group, "Russian");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(400, 728, 15, 15), group, "Spanish");
form.addField(group);
//Create checkboxes
for (int i = 0; i < 3; i++) {
PdfButtonFormField checkField = PdfFormField.createCheckBox(doc.getPdfDocument(), new Rectangle(119 + i * 69, 701, 15, 15),
"experience".concat(String.valueOf(i+1)), "Off", PdfFormField.TYPE_CHECK);
form.addField(checkField);
}
//Create combobox
String[] options = {"Any", "6.30 am - 2.30 pm", "1.30 pm - 9.30 pm"};
PdfChoiceFormField choiceField = PdfFormField.createComboBox(doc.getPdfDocument(), new Rectangle(163, 676, 115, 15),
"shift", "Any", options);
form.addField(choiceField);
//Create multiline text field
PdfTextFormField infoField = PdfTextFormField.createMultilineText(doc.getPdfDocument(),
new Rectangle(158, 625, 366, 40), "info", "");
form.addField(infoField);
//Create push button field
PdfButtonFormField button = PdfFormField.createPushButton(doc.getPdfDocument(),
new Rectangle(479, 594, 45, 15), "reset", "RESET");
button.setAction(PdfAction.createResetForm(new String[] {"name", "language", "experience1", "experience2", "experience3", "shift", "info"}, 0));
form.addField(button);
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); //關鍵的一句話
Paragraph title2 = new Paragraph("Application for employment")
.setTextAlignment(TextAlignment.CENTER)
.setFontSize(16);
doc.add(title2);
doc.add(new Paragraph("Full name:").setFontSize(12));
doc.add(new Paragraph("Native language: English French German Russian Spanish").setFontSize(12));
doc.add(new Paragraph("Experience in: cooking driving software development").setFontSize(12));
doc.add(new Paragraph("Preferred working shift:").setFontSize(12));
doc.add(new Paragraph("Additional information:").setFontSize(12));
//以下小部件的名稱只是變換一下,在後面加2
//Create text field
PdfTextFormField nameField2 = PdfTextFormField.createText(doc.getPdfDocument(),
new Rectangle(99, 753, 425, 15), "name2", "");
form.addField(nameField2); //用到之前的form
//Create radio buttons
PdfButtonFormField group2 = PdfFormField.createRadioGroup(doc.getPdfDocument(), "language2", "");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(130, 728, 15, 15), group2, "English");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(200, 728, 15, 15), group2, "French");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(260, 728, 15, 15), group2, "German");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(330, 728, 15, 15), group2, "Russian");
PdfFormField.createRadioButton(doc.getPdfDocument(), new Rectangle(400, 728, 15, 15), group2, "Spanish");
form.addField(group2);
//Create checkboxes
for (int i = 0; i < 3; i++) {
PdfButtonFormField checkField = PdfFormField.createCheckBox(doc.getPdfDocument(), new Rectangle(119 + i * 69, 701, 15, 15),
"experience2_".concat(String.valueOf(i+1)), "Off", PdfFormField.TYPE_CHECK);
form.addField(checkField);
}
//Create combobox
String[] options2 = {"Any", "6.30 am - 2.30 pm", "1.30 pm - 9.30 pm"};
PdfChoiceFormField choiceField2 = PdfFormField.createComboBox(doc.getPdfDocument(), new Rectangle(163, 676, 115, 15),
"shift2", "Any", options2);
form.addField(choiceField2);
//Create multiline text field
PdfTextFormField infoField2 = PdfTextFormField.createMultilineText(doc.getPdfDocument(),
new Rectangle(158, 625, 366, 40), "info2", "");
form.addField(infoField2);
//Create push button field
PdfButtonFormField button2 = PdfFormField.createPushButton(doc.getPdfDocument(),
new Rectangle(479, 594, 45, 15), "reset2", "RESET");
button2.setAction(PdfAction.createResetForm(new String[] {"name2", "language2", "experience2_1", "experience2_2", "experience2_3", "shift2", "info2"}, 0));
form.addField(button2);
}
}