本文目录导读:

我来为你提供几个iText生成PDF的实用案例,从基础到进阶。
环境准备
Maven依赖
<!-- iText 7 核心库 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
<!-- 如果需要操作中文字体 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.2.5</version>
</dependency>
基础案例:创建简单PDF
案例1:基础文本PDF
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import java.io.FileOutputStream;
public class BasicPdfExample {
public static void main(String[] args) throws Exception {
// 1. 创建PDF写入器
String dest = "basic_example.pdf";
PdfWriter writer = new PdfWriter(new FileOutputStream(dest));
// 2. 创建PDF文档
PdfDocument pdf = new PdfDocument(writer);
// 3. 创建文档对象
Document document = new Document(pdf);
// 4. 添加内容
// 设置中文字体
PdfFont chineseFont = PdfFontFactory.createFont(
"STSong-Light", "UniGB-UCS2-H", true);
// 标题
Paragraph title = new Paragraph("iText生成PDF示例")
.setFont(chineseFont)
.setFontSize(18)
.setBold()
.setTextAlignment(TextAlignment.CENTER);
document.add(title);
// 正文
Paragraph body = new Paragraph()
.setFont(chineseFont)
.setFontSize(12);
body.add(new Text("这是使用iText生成的第一个PDF文档。")
.setBold());
body.add(new Text("\n\niText是一个强大的PDF操作库,支持:"));
body.add(new Text("\n• 生成新的PDF文档"));
body.add(new Text("\n• 操作现有PDF"));
body.add(new Text("\n• 添加图片、表格、超链接等"));
document.add(body);
// 5. 关闭文档
document.close();
System.out.println("PDF生成成功!");
}
}
进阶案例:包含表格和图片
案例2:带表格和图片的PDF
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.layout.borders.SolidBorder;
import java.net.URL;
public class TableImagePdfExample {
public static void main(String[] args) throws Exception {
String dest = "table_image_example.pdf";
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 添加标题
document.add(new Paragraph("员工信息表")
.setFontSize(16)
.setBold()
.setTextAlignment(TextAlignment.CENTER));
// 创建表格(3列)
float[] columnWidths = {100f, 200f, 150f};
Table table = new Table(UnitValue.createPercentArray(columnWidths))
.useAllAvailableWidth();
// 添加表头
String[] headers = {"员工ID", "姓名", "部门"};
for (String header : headers) {
Cell cell = new Cell()
.add(new Paragraph(header).setBold())
.setBackgroundColor(ColorConstants.LIGHT_GRAY)
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
// 添加数据
String[][] data = {
{"001", "张三", "技术部"},
{"002", "李四", "市场部"},
{"003", "王五", "人事部"}
};
for (String[] row : data) {
for (String cellData : row) {
table.addCell(new Cell()
.add(new Paragraph(cellData))
.setTextAlignment(TextAlignment.CENTER));
}
}
// 添加表格到文档
document.add(table);
// 添加间距
document.add(new Paragraph("\n"));
// 添加图片(从文件)
try {
Image img = new Image(ImageDataFactory.create("path/to/your/image.jpg"));
img.setWidth(200);
img.setHeight(150);
document.add(img);
} catch (Exception e) {
document.add(new Paragraph("图片加载失败"));
}
// 设置页面边框
document.setBorder(new SolidBorder(ColorConstants.BLACK, 1));
document.close();
System.out.println("带表格和图片的PDF生成成功!");
}
}
高级案例:完整报表
案例3:含样式、水印和页眉页脚的报表
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.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.layout.Canvas;
public class AdvancedReportExample {
// 页眉页脚处理类
static class HeaderFooterHandler implements IEventHandler {
private String header;
private String footer;
private PdfFont font;
public HeaderFooterHandler(String header, String footer) {
this.header = header;
this.footer = footer;
try {
this.font = PdfFontFactory.createFont(
"STSong-Light", "UniGB-UCS2-H", true);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
int pageNum = pdf.getPageNumber(page);
// 页眉
Canvas headerCanvas = new Canvas(page, page.getPageSize());
headerCanvas.setFont(font)
.setFontSize(10)
.showTextAligned(header,
page.getPageSize().getWidth() / 2,
page.getPageSize().getTop() - 30,
TextAlignment.CENTER,
VerticalAlignment.TOP);
// 页脚(包含页码)
Canvas footerCanvas = new Canvas(page, page.getPageSize());
footerCanvas.setFont(font)
.setFontSize(10)
.showTextAligned(footer + " 第 " + pageNum + " 页",
page.getPageSize().getWidth() / 2,
page.getPageSize().getBottom() + 30,
TextAlignment.CENTER,
VerticalAlignment.BOTTOM);
}
}
public static void main(String[] args) throws Exception {
String dest = "report_example.pdf";
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(writer);
// 注册页眉页脚处理器
pdf.addEventHandler(PdfDocumentEvent.END_PAGE,
new HeaderFooterHandler("年度业务报告", "公司内部资料"));
Document document = new Document(pdf);
// 创建中文字体
PdfFont chineseFont = PdfFontFactory.createFont(
"STSong-Light", "UniGB-UCS2-H", true);
// 封面页
document.add(new Paragraph("\n\n\n\n"));
Paragraph title = new Paragraph("2024年度业务报告")
.setFont(chineseFont)
.setFontSize(24)
.setBold()
.setTextAlignment(TextAlignment.CENTER);
document.add(title);
document.add(new Paragraph("\n"));
Paragraph subtitle = new Paragraph("业务增长与市场分析")
.setFont(chineseFont)
.setFontSize(16)
.setTextAlignment(TextAlignment.CENTER);
document.add(subtitle);
document.add(new Paragraph("\n\n\n"));
// 可加封面的其他信息
Paragraph date = new Paragraph("2024年12月")
.setFont(chineseFont)
.setFontSize(12)
.setTextAlignment(TextAlignment.CENTER);
document.add(date);
// 新页
document.add(new AreaBreak());
// 目录页
document.add(new Paragraph("目录")
.setFont(chineseFont)
.setFontSize(18)
.setBold());
document.add(new Paragraph("1. 业务概览")
.setFont(chineseFont)
.setFontSize(12));
document.add(new Paragraph("2. 市场分析")
.setFont(chineseFont)
.setFontSize(12));
document.add(new Paragraph("3. 财务数据")
.setFont(chineseFont)
.setFontSize(12));
// 新页
document.add(new AreaBreak());
// 使用案例3的表格方法
addBusinessTable(document, chineseFont);
// 添加水印(仅在特定页面)
Thread.sleep(100); // 确保新页在前面的操作完成后
addWatermark(pdf.getLastPage(), "机密文件");
document.close();
System.out.println("完整报表生成成功!");
}
private static void addBusinessTable(Document document, PdfFont font) {
// 业务数据表格
document.add(new Paragraph("业务数据汇总")
.setFont(font)
.setFontSize(16)
.setBold()
.setTextAlignment(TextAlignment.CENTER));
float[] columnWidths = {100f, 100f, 100f, 100f};
Table table = new Table(columnWidths);
// 表头
String[] headers = {"季度", "营业收入", "净利润", "同比增长"};
for (String header : headers) {
table.addHeaderCell(new Cell()
.add(new Paragraph(header).setFont(font).setBold())
.setBackgroundColor(ColorConstants.LIGHT_GRAY)
.setTextAlignment(TextAlignment.CENTER));
}
// 数据
String[][] data = {
{"Q1", "5000万", "800万", "+5.2%"},
{"Q2", "5500万", "950万", "+12.8%"},
{"Q3", "6200万", "1200万", "+18.5%"},
{"Q4", "7000万", "1500万", "+25.1%"}
};
for (String[] row : data) {
for (String cellData : row) {
table.addCell(new Cell()
.add(new Paragraph(cellData).setFont(font))
.setTextAlignment(TextAlignment.CENTER));
}
}
document.add(table);
}
private static void addWatermark(PdfPage page, String text) {
try {
PdfCanvas canvas = new PdfCanvas(page);
PdfFont font = PdfFontFactory.createFont(
"STSong-Light", "UniGB-UCS2-H", true);
canvas.saveState()
.setFillColor(ColorConstants.GRAY)
.beginText()
.setFontAndSize(font, 60)
.moveText(100, 400)
.showText(text)
.endText()
.restoreState();
} catch (Exception e) {
e.printStackTrace();
}
}
}
内存中生成PDF
案例4:生成PDF到字节数组
import java.io.ByteArrayOutputStream;
public class PdfToByteArrayExample {
public static byte[] generatePdfInMemory() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 添加内容
document.add(new Paragraph("内存中生成的PDF")
.setFontSize(18)
.setBold()
.setTextAlignment(TextAlignment.CENTER));
document.close();
return baos.toByteArray();
}
public static void main(String[] args) throws Exception {
byte[] pdfContent = generatePdfInMemory();
// 保存到文件
try (java.io.FileOutputStream fos =
new java.io.FileOutputStream("memory_pdf.pdf")) {
fos.write(pdfContent);
}
// 或者作为HTTP响应返回
// response.setContentType("application/pdf");
// response.getOutputStream().write(pdfContent);
System.out.println("PDF数据大小: " + pdfContent.length + " bytes");
}
}
PDF加密和保护
案例5:带密码保护的PDF
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.EncryptionConstants;
import com.itextpdf.kernel.pdf.WriterProperties;
public class PdfEncryptionExample {
public static void main(String[] args) throws Exception {
String src = "example.pdf";
String dest = "encrypted_example.pdf";
// 创建受保护的PDF
WriterProperties writerProperties = new WriterProperties()
.setStandardEncryption(
"user_password".getBytes(), // 用户密码
"owner_password".getBytes(), // 所有者密码
EncryptionConstants.ALLOW_PRINTING, // 权限
EncryptionConstants.ENCRYPTION_AES_128 // 加密算法
);
PdfWriter writer = new PdfWriter(dest, writerProperties);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
document.add(new Paragraph("这是加密的PDF文档"));
document.close();
// 读取加密的PDF
PdfReader reader = new PdfReader(dest,
new ReaderProperties().setPassword("user_password".getBytes()));
PdfDocument readPdf = new PdfDocument(reader);
Document readDocument = new Document(readPdf);
// 读取文档内容...
readDocument.close();
}
}
实用技巧
批量生成PDF
public class BatchPdfGenerator {
public static void generateMultiplePdfs(List<Map<String, String>> records,
String outputDir) throws Exception {
for (int i = 0; i < records.size(); i++) {
Map<String, String> record = records.get(i);
generatePdf(record, outputDir + "/report_" + i + ".pdf");
}
}
private static void generatePdf(Map<String, String> data, String dest)
throws Exception {
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 动态生成内容
for (Map.Entry<String, String> entry : data.entrySet()) {
document.add(new Paragraph(entry.getKey() + ": " + entry.getValue()));
}
document.close();
}
}
注意事项
- 字体问题:中文必须使用支持中文的字体
- 资源管理:记得关闭Document和PdfDocument
- 性能考虑:批量生成时考虑使用内存中的字节流
- 错误处理:添加合适的异常处理
- 内存管理:处理大文件时注意内存使用
这些案例覆盖了iText最常见的使用场景,你可以根据实际需求进行调整和扩展。