Preface
In the previous chapters 1 to 3, we always created a new PDF document with iText from scratch. In the last few examples in Chapter 4, we used an existing PDF document, used the existing PDF to read the form and filled out our own form or pre-filled the defined form. In this chapter, we will use to PdfReader
read an existing PDF file, or use an PdfWriter
object to create a new one PdfDocument
.
Add notes and content
In the previous chapter, we read a PDF document with a form, and then filled in the content. In this chapter, we will conduct in-depth operations. We first add a document comment, some text and a new check box, as shown in Figure 1:
The next step is that we added comments in Chapter 4 as the code in the content:
PdfDocument pdfDoc =
new PdfDocument(new PdfReader(src), new PdfWriter(dest));
// add content
pdfDoc.close();
We add the corresponding content in the //add content section. First, we use PdfDocument
examples to add comments to a page:
PdfAnnotation ann = new PdfTextAnnotation(new Rectangle(400, 795, 0, 0))
.setTitle(new PdfString("iText"))
.setContents("Please, fill out the form.")
.setOpen(true);
pdfDoc.getFirstPage().addAnnotation(ann);
If we want to add content to the content stream, we need to create an PdfCancas
object. We can pass in an PdfPage
object PdfCanvas
constructor:
PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
canvas.beginText().setFontAndSize(
PdfFontFactory.createFont(FontConstants.HELVETICA), 12)
.moveText(265, 597)
.showText("I agree to the terms and conditions.")
.endText();
The code for adding text is similar to the code we wrote in Chapter 2. Whether you are creating a document from scratch or adding content to an existing document, you can use the code we wrote. Of course, PdfAcroForm
adding fields to the instance is the same as the previous example:
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
PdfButtonFormField checkField = PdfFormField.createCheckBox(
pdfDoc, new Rectangle(245, 594, 15, 15),
"agreement", "Off", PdfFormField.TYPE_CHECK);
checkField.setRequired(true);
form.addField(checkField);
Finally, since we have added an extra field, we want to change the reset action:
form.getField("reset").setAction(PdfAction.createResetForm(
new String[]{"name", "language", "experience1", "experience2",
"experience3", "shift", "info", "agreement"}, 0))
Change the properties of form fields
In the previous example in Chapter 4, we filled in the content of the form. Here, we can try to change the attributes of the field, add or delete.
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
Map<String, PdfFormField> fields = form.getFormFields();
fields.get("name").setValue("James Bond").setBackgroundColor(Color.ORANGE);
fields.get("language").setValue("English");
fields.get("experience1").setValue("Yes");
fields.get("experience2").setValue("Yes");
fields.get("experience3").setValue("Yes");
List<PdfString> options = new ArrayList<PdfString>();
options.add(new PdfString("Any"));
options.add(new PdfString("8.30 am - 12.30 pm"));
options.add(new PdfString("12.30 pm - 4.30 pm"));
options.add(new PdfString("4.30 pm - 8.30 pm"));
options.add(new PdfString("8.30 pm - 12.30 am"));
options.add(new PdfString("12.30 am - 4.30 am"));
options.add(new PdfString("4.30 am - 8.30 am"));
PdfArray arr = new PdfArray(options);
fields.get("shift").setOptions(arr);
fields.get("shift").setValue("Any");
PdfFont courier = PdfFontFactory.createFont(FontConstants.COURIER);
fields.get("info")
.setValue("I was 38 years old when I became a 007 agent.", courier, 7);
Here we focus on the following lines:
- Line 3: We set
name
the value of the fieldJames Bond
, and we set the background color of this field toColor.ORANGE
- Lines 9-17: Created a Java
List
to add more options (lines 8-15), then convert thisList
toPdfArray
(line 16), and finally use this array to update theshift
fields - Lines 19-21: We create a new one
PdfFont
, and then use this new font and new font size asinfo
the parameters of the field setting value method.
Let us see if there is any change after adding these codes, as shown in Figure 2:
We can see that the shift
field has more options, but we don't see name
the background of the field, we can't know info
whether the field has changed. Has an error occurred? In fact, there is no error. All fields are currently highlighted and the blue highlight color covers the background color. We can click Highlight Existing Fields
to see what else happens, as shown in Figure 3:
Everything is as we expected. But we did not encounter such a situation: before closing PdfDocument
, we added a form.flattenFields();
statement, this time the form is locked, we have no form, for this situation, we will discuss in the next chapter. Now, let's see if we can perform some other operations on pdf documents without forms.
Add header, footer and watermark
We recall the PDF of UFO information in Chapter 3, we will create a similar ufo.pdf file, as shown in Figure 4:
It can be seen that the ufo.pdf we created is not as cool as the one created in Chapter 3. If we add a header and a footer (showing the number of pages/total pages) and a watermark to it, what should we do? , As shown in Figure 5:
In the above picture, we don’t know the total number of pages when we add the footer like in Chapter 3. Now that we know the total number of pages, we can add "1" of "4", "2" of "4 "Wait
When creating a document from scratch, you can create a placeholder for the total number of pages. Once all the pages are created, we can add the total number of pages to the placeholder, but this is outside the scope of this introductory tutorial.
The following code shows how to add content to each page of a known document:
PdfDocument pdfDoc =
new PdfDocument(new PdfReader(src), new PdfWriter(dest));
Document document = new Document(pdfDoc);
Rectangle pageSize;
PdfCanvas canvas;
int n = pdfDoc.getNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = pdfDoc.getPage(i);
pageSize = page.getPageSize();
canvas = new PdfCanvas(page);
// add new content
}
pdfDoc.close();
We use pdfDoc
objects to create an Document
instance. We will use this document
object to add content. We will also use pdfDoc
objects to find the total number of pages in the original PDF. We traverse all the pages and get the PdfPage
object of each page . The following code is //add new content
what is done:
//Draw header text
canvas.beginText().setFontAndSize(
PdfFontFactory.createFont(FontConstants.HELVETICA), 7)
.moveText(pageSize.getWidth() / 2 - 24, pageSize.getHeight() - 10)
.showText("I want to believe")
.endText();
//Draw footer line
canvas.setStrokeColor(Color.BLACK)
.setLineWidth(.2f)
.moveTo(pageSize.getWidth() / 2 - 30, 20)
.lineTo(pageSize.getWidth() / 2 + 30, 20).stroke();
//Draw page number
canvas.beginText().setFontAndSize(
PdfFontFactory.createFont(FontConstants.HELVETICA), 7)
.moveText(pageSize.getWidth() / 2 - 7, 10)
.showText(String.valueOf(i))
.showText(" of ")
.showText(String.valueOf(n))
.endText();
//Draw watermark
Paragraph p = new Paragraph("CONFIDENTIAL").setFontSize(60);
canvas.saveState();
PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.2f);
canvas.setExtGState(gs1);
document.showTextAligned(p,
pageSize.getWidth() / 2, pageSize.getHeight() / 2,
pdfDoc.getPageNumber(page),
TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
canvas.restoreState();
The total steps are divided into four parts:
- Header (lines 2-6): We use the low-level text api mentioned in Chapter 2 to add at the top of each page
"I want to believe"
- Footer line (lines 8-11): We use low-level drawing api to draw a line at the bottom of each page
- Footer with page number (lines 13-19): We use low-level text api to add the current page number
"of"
,, and the total number of pages at the bottom of each page . - Watermark (lines 21-28): We create a
Paragrah
watermark with text . Then we change the transparency of the canvas. Finally, we add thisParagrah
to the document, using theshowTextAligned()
method to position the watermark in the middle of each page and tilt it at 45 degrees.
Here, we did some special work when adding watermark. We changed the canvas
image state of the object, and then we document
added text to each page. Internally, iText will find that we have used the PafCanvas
instance of the current page and showTextAligned
want to canvas
write the same content. In this way, we can Use the combination of low-level api and some simple methods (such as high-level api) ( compared with adding watermark in Chapter 3 , it is indeed a lot more convenient). In the example at the end of this chapter, we will change the page size and the orientation of each page of upf.pdf.
Change page size and orientation
The effect of the new pdf document is shown in Figure 6:
We can find that each page has become larger, and the second page is upside down and down. Let's take a look at the code:
PdfDocument pdfDoc =
new PdfDocument(new PdfReader(src), new PdfWriter(dest));
float margin = 72;
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
PdfPage page = pdfDoc.getPage(i);
// change page size
Rectangle mediaBox = page.getMediaBox();
Rectangle newMediaBox = new Rectangle(
mediaBox.getLeft() - margin, mediaBox.getBottom() - margin,
mediaBox.getWidth() + margin * 2, mediaBox.getHeight() + margin * 2);
page.setMediaBox(newMediaBox);
// add border
PdfCanvas over = new PdfCanvas(page);
over.setStrokeColor(Color.GRAY);
over.rectangle(mediaBox.getLeft(), mediaBox.getBottom(),
mediaBox.getWidth(), mediaBox.getHeight());
over.stroke();
// change rotation of the even pages
if (i % 2 == 0) {
page.setRotation(180);
}
}
pdfDoc.close();
It can be found that we don't need an Document
instance here , we only need an PdfDocument
instance. We traverse all the pages (line 4) and get the PdfPage
instance of each page (line 5):
- A page can have a different boundary, which
/MediaBox
is basically a page size (the details can Baidu PDF MediaBox), then we get aRectangle
boundary as the original page (line 7), to create a larger one foot according to the boundary edgeRectangle
to As a new page boundary size, we finally usesetMediaBox()
to change the page size - We created the
PdfCanvas
object on the page , and then used the gray brush to draw themediaBox
border (lines 14-17) - For even pages, we rotate the page 180 degrees (line 19)
Changing a known PDF document requires a lot of knowledge about PDF, such as /MediaBox
the concept of. In order to make our example simple, we will avoid some other details. For example, in the above example, we did not check that there is an CropBox
object in the document . If there is this object, making it /MediaBox
larger will not bring any visual Transform. So it will take more chapters to discuss these issues in depth.
to sum up
In the previous chapter, we learned about interactive PDF forms. In this chapter, we continue to operate these forms: add comments, some text and additional fields, we also change some attributes of the fields while filling the form.
Then we discussed those PDF documents without interaction. First, we added headers, footers and watermarks, and then we changed the page size and orientation of the known documents.
In the next chapter, we will zoom and tile the known documents, and then we will learn how to combine multiple documents into one PDF.
PS: My itext7 column is online. It contains my carefully translated and compiled knowledge about itext7. Please pay attention to it. I have received some rewards and encouragement before. I will continue to update itext7 and share the latest knowledge!