@[TOC] Recently there is a need to generate a new PDF based on the existing PDF template. There is a lot of information on the Internet
The first step is to create a template
Create a template from an existing PDF using Adobe Acrobat Pro
2 Go to www.pdfescape.com/open/ and create a template based on the existing PDF
The second step introduces the POM
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
Copy the code
Step 3 Generate a PDF from the template
JAVA uses IText to generate PDF documents from templates
package com.pdf;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
public class Test {
public static void main(String[] args) throws Exception {
export();
System.out.println("Generated complete");
}
public static void export(a){
try {
// The path where the PDF template resides is the path where the PDF template is downloaded after the website is completed
String fileName = "D:/testpdf.pdf";
PdfReader reader = new PdfReader(fileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper ps = new PdfStamper(reader, bos);
// Use Chinese fonts
BaseFont bf = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
fontList.add(bf);
AcroFields fields = ps.getAcroFields();
fields.setSubstitutionFonts(fontList);
fillData(fields, data());
// This must be called, otherwise the document will not be generated
ps.setFormFlattening(true);
ps.close();
// The generated PDF path
OutputStream fos = new FileOutputStream("D:/result.pdf");
fos.write(bos.toByteArray());
fos.flush();
fos.close();
bos.close();
}catch(Exception e){ e.printStackTrace(); }}/** * Populates the data in the template */
public static void fillData(AcroFields fields, Map<String, String> data) {
try {
for (String key : data.keySet()) {
String value = data.get(key);
// Assign a value to the field. Note that the field name is case sensitivefields.setField(key, value); }}catch(Exception e) { e.printStackTrace(); }}/** * populates the data source * where data holds the key value corresponding to the text field value in the PDF template */
public static Map<String, String> data(a) {
Map<String, String> data = new HashMap<String, String>();
data.put("schoolName"."International test test \r\ N test test");
data.put("userName"."yvioo");
data.put("date"."2020/7");
returndata; }}Copy the code
How to populate image data
public static void fillImage(AcroFields fields, Map<String, String> imagesData, PdfStamper ps) throws IOException, DocumentException {
for(String key : imagesData.keySet()) {
String value = imagesData.get(key);
// Get the template page corresponding to the current image field
int pageNo = fields.getFieldPositions(key).get(0).page;
// Get the position of the template corresponding to the current image field
Rectangle signRect = fields.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// Read the image from the path
Image image = Image.getInstance(value);
// Get the image page
PdfContentByte pdfContentByte = ps.getOverContent(pageNo);
// Image size ADAPTS
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// Add imagesimage.setAbsolutePosition(x, y); pdfContentByte.addImage(image); }}Copy the code
How do I wrap the filled data
public static void fillChunkData(AcroFields fields, Map<String, String> data, PdfStamper ps) throws IOException, DocumentException {
// Assign a value to the field. Note that the field name is case sensitive
for (String key : data.keySet()) {
// Get the template page corresponding to the current image field
int page = fields.getFieldPositions(key).get(0).page;
// Get the position of the template corresponding to the current image field
Rectangle rectangle = fields.getFieldPositions(key).get(0).position;
float left = rectangle.getLeft();
float right = rectangle.getRight();
float top = rectangle.getTop();
float bottom = rectangle.getBottom();
// Set the Chinese font
BaseFont baseFont = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H".false);
// Set the font size and style
Font font = new Font(baseFont, 10, Font.NORMAL);
PdfContentByte pdfContentByte = ps.getOverContent(page);
// Set the content and position of the fill field
ColumnText columnText = new ColumnText(pdfContentByte);
Rectangle r = new Rectangle(left, bottom, right, top);
columnText.setSimpleColumn(r);
// Split the data
String checkInfo = data.get(key);
String[] info = checkInfo.split("\ \ |");
if (info.length == 2) {
// Populate the first row of the field
Chunk chunk = new Chunk("First row of data");
Paragraph paragraph = new Paragraph(12, chunk);
paragraph.setSpacingBefore(8);
columnText.addText(paragraph);
paragraph.setFont(font);
// Set the content to the right
//paragraph.setAlignment(Element.ALIGN_RIGHT);
columnText.addElement(paragraph);
Chunk chunk2 = new Chunk("Second row of data");
Paragraph paragraph2 = new Paragraph(12, chunk2);
paragraph2.setSpacingBefore(8); columnText.addText(paragraph2); paragraph2.setFont(font); columnText.addElement(paragraph2); } columnText.go(); }}Copy the code
conclusion
It is very easy to get started, mainly some special operations, such as newline, right, font color, size and so on style related issues, after all, need to be generated to see the effect. Note: 1. Itext-asian related JAR packages need to be introduced for Chinese support