目錄
一、前期準(zhǔn)備
1、中文字體文件
2、maven依賴
二、創(chuàng)建PDF文檔方法
三、通過可填充PDF模板將業(yè)務(wù)參數(shù)進(jìn)行填充
1、?設(shè)置可填充的PDF表單
2、代碼開干,代碼填充可編輯PDF并另存文件
一、前期準(zhǔn)備
1、中文字體文件
本演示使用的是iText 7版本,如果沒有中文字體,那生成的PDF文檔涉及中文的區(qū)域都無法顯示。
現(xiàn)有查找到的PDF免費(fèi)下載網(wǎng)址如下:
- 阿里巴巴矢量圖標(biāo)庫:除了圖標(biāo)庫,該網(wǎng)站還提供了一些免費(fèi)的字體庫供下載和使用。
- 字由:字由是一個(gè)專注于中文字體的網(wǎng)站,提供了一些優(yōu)質(zhì)的免費(fèi)字體供下載。
- 字體中國(guó):字體中國(guó)是一個(gè)提供中文字體下載的網(wǎng)站,包含了許多中文設(shè)計(jì)師的作品。
- 站長(zhǎng)之家字體庫:站長(zhǎng)之家提供了大量的免費(fèi)字體庫,包含了各種中文字體和英文字體。
2、maven依賴
<dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>7.2.5</version>
</dependency>
</dependencies>
二、創(chuàng)建PDF文檔方法
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class CreatePdf {
//文件根目錄
public static String RootPath = "D:/files-pdf/";
// 設(shè)置字體文件路徑
//注意:如果沒有中文字體,那PDF內(nèi)容涉及中文的區(qū)域都不顯示
public static String fontPath = RootPath + "ZiTiQuanWeiJunHei-W1-2.ttf";
public static void main(String[] args) {
String pdfName = "testContent.pdf";
// 創(chuàng)建 PdfWriter 和 PdfDocument
PdfWriter writer = null;
try {
writer = new PdfWriter(pdfName + ".pdf");
} catch (FileNotFoundException e) {
System.out.println("創(chuàng)建PdfWriter失敗。。。。。");
e.printStackTrace();
return;
}
PdfDocument pdfDocument = new PdfDocument(writer);
// 創(chuàng)建 Document
Document document = new Document(pdfDocument);
// 設(shè)置頁面的邊距
documentMargins(document);
// 設(shè)置頁眉和頁腳
headerAndFooter(pdfDocument);
//編寫PDF主體的文檔內(nèi)容 , 這一塊是主要編寫位置
setContent(document);
//添加水印
addWatermark(pdfDocument);
// 關(guān)閉對(duì)象
document.close(); //document文檔要在輸出前關(guān)閉,不然會(huì)提示“java.nio.file.NoSuchFileException: editable.pdf”
pdfDocument.close();
// 將生成的 PDF 文件移動(dòng)到指定目錄下
downloadPdf(RootPath, pdfName);
}
/**
* 獲取設(shè)置的字體
*
* @return PdfFont 字體
*/
private static PdfFont getFont() {
// 設(shè)置中文字體
PdfFont font = null;
try {
font = PdfFontFactory.createFont(fontPath);
} catch (IOException e) {
System.out.println("字體獲取失敗。。。。。。。。。。。");
e.printStackTrace();
return null;
}
return font;
}
/**
* 設(shè)置頁面的邊距
*
* @param document 內(nèi)容文檔
*/
private static void documentMargins(Document document) {
// 上、右、下、左
int margins = 80;
document.setMargins(margins, margins, margins, margins);
}
/**
* 設(shè)置頁眉頁腳
*
* @param pdfDocument PDF文檔
*/
private static void headerAndFooter(PdfDocument pdfDocument) {
pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new IEventHandler() {
@Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfPage page = docEvent.getPage();
PdfCanvas canvas = new PdfCanvas(page);
// 創(chuàng)建頁眉
Rectangle pageSize = page.getPageSize();
canvas.beginText()
.setFontAndSize(getFont(), 10)
.moveText(pageSize.getWidth() / 2, pageSize.getTop() - 20)
.showText("這是頁眉")
.endText();
// 創(chuàng)建頁腳
canvas.beginText()
.setFontAndSize(getFont(), 10)
.moveText(pageSize.getWidth() / 2, pageSize.getBottom() + 20)
.showText("這是頁腳")
.endText();
canvas.release();
}
});
}
/**
* 添加水印
*
* @param pdfDocument PDF文檔
* @throws MalformedURLException
*/
private static void addWatermark(PdfDocument pdfDocument) {
// 加載水印圖片
String watermarkImage = RootPath + "zm5.jpg";
Image image = null;
try {
image = new Image(ImageDataFactory.create(watermarkImage));
} catch (MalformedURLException e) {
System.out.println("獲取水印圖片失敗 , e : " + e);
e.printStackTrace();
return;
}
// 獲取 PDF 頁面的大小,此處是要以頁面區(qū)域做參考,后續(xù)好設(shè)置對(duì)應(yīng)的坐標(biāo)填充水印
Rectangle rectanglePageSize = pdfDocument.getDefaultPageSize();
// 遍歷每個(gè)頁面,添加水印
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
//創(chuàng)建PDF畫布
PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(i));
// 創(chuàng)建 Canvas 畫布對(duì)象,設(shè)置位置和大小
Canvas canvas = new Canvas(pdfCanvas, rectanglePageSize, true);
// 在水印畫布上添加圖片,并設(shè)置透明度和位置
// 上、右、下、左
image.setOpacity(0.8f).setMargins(600, 200, 0, 300);
canvas.add(image);
// 關(guān)閉水印畫布
canvas.close();
}
}
/**
* 生成的 PDF 文件移動(dòng)到指定目錄下
*
* @param rootPath 存儲(chǔ)目錄
* @param pdfName PDF文件名
* @return
*/
private static String downloadPdf(String rootPath, String pdfName) {
// 假設(shè)生成的 PDF 文件路徑為 sourcePath
Path sourcePath = Paths.get(pdfName + ".pdf");
// 假設(shè)目標(biāo)目錄路徑為 targetDirectoryPath
Path targetDirectoryPath = Paths.get(rootPath);
// 移動(dòng)文件到目標(biāo)目錄
Path targetPath = null;
try {
targetPath = Files.move(sourcePath, targetDirectoryPath.resolve(sourcePath.getFileName()), StandardCopyOption.REPLACE_EXISTING);
// 輸出成功信息
System.out.println("文件移動(dòng)成功,目標(biāo)路徑:" + targetPath);
return targetPath.toString();
} catch (IOException e) {
// 輸出失敗信息
System.out.println("文件移動(dòng)失敗,目標(biāo)路徑:" + targetPath);
e.printStackTrace();
return null;
}
}
/**
* PDF主體內(nèi)容
*
* @param document 文檔
*/
private static void setContent(Document document) {
// 設(shè)置中文字體
PdfFont font = getFont();
/******************************** 段落內(nèi)容由 Paragraph 區(qū)域編寫 ******************************************/
// 創(chuàng)建段落標(biāo)題
Paragraph paragraphTitle = new Paragraph().setFont(font);
// setBold:設(shè)置粗體,setItalic:斜體,setUnderline:下劃線
paragraphTitle.add("這是一份PDF測(cè)試文檔").setBold().setFontSize(12);
// 設(shè)置段落的對(duì)齊方式為居中
paragraphTitle.setTextAlignment(TextAlignment.CENTER);
document.add(paragraphTitle);
// 創(chuàng)建一個(gè)可編輯的段落
Paragraph nameOfStaff = new Paragraph().setFont(font).setFontSize(10);
nameOfStaff.add("Name of Developer / 開發(fā)人員:");
document.add(nameOfStaff);
Paragraph fullname = new Paragraph().setFont(font).setFontSize(10);
fullname.add("____________________(Note: 請(qǐng)寫全名)");
document.add(fullname);
Paragraph paragraph1 = new Paragraph().setFont(font).setFontSize(9);
paragraph1.add("這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!" +
"這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!" +
"這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!" +
"這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!" +
"這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!這是段落內(nèi)容!");
document.add(paragraph1);
Paragraph declare = new Paragraph().setFont(font).setFontSize(9);
declare.add("I hereby declare that:");
document.add(declare);
Paragraph section = new Paragraph().setFont(font).setFontSize(9).setBold().setUnderline();
section.add("多選項(xiàng)聲明確認(rèn)!Multiple option declaration confirmation!");
document.add(section);
// 創(chuàng)建一個(gè)帶有復(fù)選框的列表
Paragraph paragraph2 = new Paragraph().setFont(font).setFontSize(9);
paragraph2.add("(Please tick in the box as appropriate)").add("\n");
paragraph2.add("口 聲明內(nèi)容1。。。聲明內(nèi)容1。。。聲明內(nèi)容1。。。聲明內(nèi)容1。。。聲明內(nèi)容1。。。聲明內(nèi)容1。。。").add("\n");
paragraph2.add("口 聲明內(nèi)容2。。。聲明內(nèi)容2。。。聲明內(nèi)容2。。。聲明內(nèi)容2。。。聲明內(nèi)容2。。。聲明內(nèi)容2。。。").add("\n");
document.add(paragraph2);
/******************************** 表格由 Table 區(qū)域編寫 ******************************************/
// 創(chuàng)建表格并設(shè)置列數(shù)和默認(rèn)寬度
Table table = new Table(4);
// table.setMaxWidth(1000); //固定式寬度
// table.setAutoLayout(); //根據(jù)內(nèi)容自適應(yīng)寬度
table.setWidth(UnitValue.createPercentValue(100)); //頁面總寬固定
// 添加表格標(biāo)題(合并4列)
Cell titleCell = new Cell(1, 4);
// 創(chuàng)建文本對(duì)象
titleCell.add(new Paragraph("Table Title"));
titleCell.setTextAlignment(TextAlignment.CENTER);
table.addHeaderCell(titleCell);
// 添加表頭
table.addHeaderCell("Header 1");
table.addHeaderCell("Header 2");
table.addHeaderCell("Header 3");
table.addHeaderCell("Header 4");
// 添加表格內(nèi)容
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
Cell cell = new Cell()
.setFont(font)
.add(new Paragraph("行 " + (i + 1) + ", Col " + (j + 1)))
.setWidth(UnitValue.createPercentValue(25));
table.addCell(cell);
}
}
// 設(shè)置表格樣式
table.setHorizontalAlignment(HorizontalAlignment.CENTER);
// 將表格添加到文檔中
document.add(table);
/******************************** 內(nèi)容區(qū)域編寫END ******************************************/
}
}
三、通過可填充PDF模板將業(yè)務(wù)參數(shù)進(jìn)行填充
1、?設(shè)置可填充的PDF表單
至于編輯器自行查找,免費(fèi)的基本大多會(huì)添加水印。
設(shè)置成功后,如下圖,可編輯區(qū)高亮顯示
文章來源:http://www.zghlxwxcb.cn/news/detail-465440.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-465440.html
2、代碼開干,代碼填充可編輯PDF并另存文件
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class FillingPdfTemplate {
//文件根目錄
public static String RootPath = "D:/files-pdf/";
// 設(shè)置字體文件路徑
//注意:如果沒有中文字體,那PDF內(nèi)容涉及中文的區(qū)域都不顯示
public static String fontPath = RootPath + "ZiTiQuanWeiJunHei-W1-2.ttf";
public static void main(String[] args) {
Map<String, String> mapParam = new HashMap<>();
mapParam.put("fullname", "某某某");
mapParam.put("Check Box1","On");
mapParam.put("Check Box2", "Off");
mapParam.put("account1", "account1");
mapParam.put("broker1", "broker1");
mapParam.put("number1", "number1");
mapParam.put("security1", "security1");
mapParam.put("sharehold1", "sharehold1");
mapParam.put("clp1", "clp1");
mapParam.put("shares1", "shares1");
mapParam.put("sharehold3", "");
mapParam.put("clp3", "");
mapParam.put("shares3", "");
mapParam.put("name1", "某某某");
mapParam.put("position", "XXX高級(jí)");
mapParam.put("company", "深圳市XXX科技有限公司");
mapParam.put("date", "2023-05-24");
String templatePdfPath = RootPath + "Acrobat-demo.pdf";
String destPdfPath = RootPath + "Acrobat-demo-result.pdf";
replaceTextFieldPdf(templatePdfPath, destPdfPath, mapParam);
}
/**
* 獲取設(shè)置的字體
*
* @return PdfFont 字體
*/
private static PdfFont getFont() {
// 設(shè)置中文字體
PdfFont font = null;
try {
font = PdfFontFactory.createFont(fontPath);
} catch (IOException e) {
System.out.println("字體獲取失敗。。。。。。。。。。。");
e.printStackTrace();
return null;
}
return font;
}
/**
* 替換PDF文本表單域變量
*
* @param templatePdfPath 要替換的pdf全路徑
* @param params 替換參數(shù)
* @param destPdfPath 替換后保存的PDF全路徑
* @throws IOException
*/
public static final void replaceTextFieldPdf(String templatePdfPath, String destPdfPath,
Map<String, String> params) {
PdfDocument pdfDoc = null;
try {
pdfDoc = new PdfDocument(new PdfReader(templatePdfPath), new PdfWriter(destPdfPath));
} catch (IOException e) {
e.printStackTrace();
}
//獲取表單信息
PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(pdfDoc, true);
//遍歷填充預(yù)設(shè)的值
Set<Map.Entry<String, String>> entries = params.entrySet();
entries.stream().forEach(entry -> {
if(pdfAcroForm.getField(entry.getKey()) != null){
// 設(shè)置表單字段的值
//復(fù)選框類型的:1勾選,2圓圈,3叉叉,4菱形,5方塊,6星星
//如果不想復(fù)選框被選中,要設(shè)置為"Off",選中設(shè)置為"On",注意大小寫
pdfAcroForm.getField(entry.getKey()).setCheckType(1).setValue(entry.getValue() , true).setFont(getFont());
}
});
// 添加表單字段
// PdfTextFormField textField = PdfFormField.createText(pdfDoc, new Rectangle(100, 100, 200, 20), "newField", "");
// pdfAcroForm.addField(textField);
//表單扁平化,設(shè)置后生成的文檔不可再編輯
// pdfAcroForm.flattenFields();
pdfDoc.close();
}
}
到了這里,關(guān)于JAVA-創(chuàng)建PDF文檔的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!