本文目录导读:

我将为您提供几个Java生成PDF的实用案例,使用最流行的iText库。
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生成案例
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.io.font.constants.StandardFonts;
import java.io.File;
import java.io.FileOutputStream;
public class SimplePdfGenerator {
public static void generateSimplePdf(String dest) throws Exception {
// 创建PDF写入器
PdfWriter writer = new PdfWriter(new FileOutputStream(dest));
// 创建PDF文档
PdfDocument pdfDoc = new PdfDocument(writer);
// 设置文档属性
pdfDoc.getDocumentInfo().setTitle("Java生成PDF示例");
pdfDoc.getDocumentInfo().setAuthor("张三");
pdfDoc.getDocumentInfo().setSubject("iText使用教程");
pdfDoc.getDocumentInfo().setKeywords("Java, PDF, iText");
// 创建Document对象(带边距)
Document document = new Document(pdfDoc);
// 添加内容
document.add(new Paragraph("这是一个简单的PDF生成示例"));
document.add(new Paragraph("第二行内容,演示多行文本"));
// 关闭文档
document.close();
System.out.println("PDF生成成功!");
}
}
带样式的PDF生成(含中文支持)
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.kernel.colors.*;
import com.itextpdf.kernel.font.*;
import com.itextpdf.layout.properties.*;
import java.io.FileOutputStream;
public class StyledPdfGenerator {
public static void generateStyledPdf(String dest) throws Exception {
PdfWriter writer = new PdfWriter(new FileOutputStream(dest));
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 创建中文字体
PdfFont chineseFont = PdfFontFactory.createFont(
"STSong-Light",
"UniGB-UCS2-H",
PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED
);
// 标题
Paragraph title = new Paragraph("公司年度报告")
.setFont(chineseFont)
.setFontSize(24)
.setBold()
.setTextAlignment(TextAlignment.CENTER)
.setFontColor(ColorConstants.BLUE)
.setMarginBottom(20);
document.add(title);
// 副标题
Paragraph subtitle = new Paragraph("2023年度经营情况总结")
.setFont(chineseFont)
.setFontSize(18)
.setFontColor(ColorConstants.GRAY)
.setTextAlignment(TextAlignment.CENTER)
.setMarginBottom(30);
document.add(subtitle);
// 正文内容
Paragraph body1 = new Paragraph("一、经营概况")
.setFont(chineseFont)
.setFontSize(14)
.setBold()
.setMarginBottom(10);
document.add(body1);
Paragraph body2 = new Paragraph("本年度公司经营状况良好,实现营业收入1.2亿元,同比增长15%。\n"
+ "利润总额达到3000万元,创历史新高,研发投入占比持续提升,达到8%。")
.setFont(chineseFont)
.setFontSize(12)
.setLineHeight(1.5f)
.setMarginBottom(20);
document.add(body2);
// 添加表格
Table table = new Table(3);
table.setWidth(UnitValue.createPercentValue(100));
// 表头
String[] headers = {"项目", "金额(万元)", "同比增长"};
for (String header : headers) {
Cell cell = new Cell()
.add(new Paragraph(header).setFont(chineseFont).setBold())
.setBackgroundColor(ColorConstants.LIGHT_GRAY)
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
// 数据行
String[][] data = {
{"营业收入", "12000", "15%"},
{"净利润", "3000", "12%"},
{"研发投入", "960", "8%"}
};
for (String[] row : data) {
for (String cellData : row) {
Cell cell = new Cell()
.add(new Paragraph(cellData).setFont(chineseFont))
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
}
document.add(table);
document.close();
System.out.println("带样式的PDF生成成功!");
}
}
生成PDF表格案例
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.kernel.colors.*;
import com.itextpdf.layout.properties.*;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
public class TablePdfGenerator {
// 模拟数据类
public static class Employee {
private String name;
private String department;
private double salary;
private String email;
public Employee(String name, String department, double salary, String email) {
this.name = name;
this.department = department;
this.salary = salary;
this.email = email;
}
// getters and setters...
public String getName() { return name; }
public String getDepartment() { return department; }
public double getSalary() { return salary; }
public String getEmail() { return email; }
}
public static void generateEmployeeTablePdf(String dest) throws Exception {
// 准备数据
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("张三", "技术部", 15000, "zhangsan@example.com"));
employees.add(new Employee("李四", "市场部", 12000, "lisi@example.com"));
employees.add(new Employee("王五", "人事部", 10000, "wangwu@example.com"));
employees.add(new Employee("赵六", "财务部", 13000, "zhaoliu@example.com"));
PdfWriter writer = new PdfWriter(new FileOutputStream(dest));
PdfDocument pdfDoc = new PdfDocument(writer);
// 设置页面为横向
pdfDoc.setDefaultPageSize(PageSize.A4.rotate());
Document document = new Document(pdfDoc);
// 创建中文字体
PdfFont chineseFont = PdfFontFactory.createFont(
"STSong-Light",
"UniGB-UCS2-H",
PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED
);
// 标题
document.add(new Paragraph("员工信息表")
.setFont(chineseFont)
.setFontSize(20)
.setBold()
.setTextAlignment(TextAlignment.CENTER)
.setMarginBottom(20));
// 创建表格:4列
float[] columnWidths = {3, 3, 3, 4}; // 列宽比例
Table table = new Table(UnitValue.createPercentArray(columnWidths));
table.setWidth(UnitValue.createPercentValue(100));
// 添加表头
String[] headers = {"姓名", "部门", "薪资(元/月)", "邮箱"};
for (String header : headers) {
Cell headerCell = new Cell()
.add(new Paragraph(header).setFont(chineseFont).setBold())
.setBackgroundColor(ColorConstants.DARK_GRAY)
.setFontColor(ColorConstants.WHITE)
.setTextAlignment(TextAlignment.CENTER)
.setPadding(8);
table.addCell(headerCell);
}
// 添加数据
for (int i = 0; i < employees.size(); i++) {
Employee emp = employees.get(i);
// 交替行颜色
Color rowColor = (i % 2 == 0) ? ColorConstants.LIGHT_GRAY :
ColorConstants.WHITE;
table.addCell(createCell(emp.getName(), chineseFont, rowColor));
table.addCell(createCell(emp.getDepartment(), chineseFont, rowColor));
table.addCell(createCell(String.format("%.2f", emp.getSalary()),
chineseFont, rowColor));
table.addCell(createCell(emp.getEmail(), chineseFont, rowColor));
}
document.add(table);
document.close();
System.out.println("员工表格PDF生成成功!");
}
private static Cell createCell(String content, PdfFont font, Color bgColor) {
return new Cell()
.add(new Paragraph(content).setFont(font))
.setBackgroundColor(bgColor)
.setTextAlignment(TextAlignment.CENTER)
.setPadding(6);
}
}
带图片和图表的PDF
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.layout.properties.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
public class ImagePdfGenerator {
public static void generateImagePdf(String dest) throws Exception {
PdfWriter writer = new PdfWriter(new FileOutputStream(dest));
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 创建中文字体
PdfFont chineseFont = PdfFontFactory.createFont(
"STSong-Light",
"UniGB-UCS2-H",
PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED
);
// 添加标题
document.add(new Paragraph("包含图片的PDF文档")
.setFont(chineseFont)
.setFontSize(18)
.setBold()
.setMarginBottom(20));
// 方式1:从文件添加图片
String imagePath = "path/to/your/image.jpg";
if (new java.io.File(imagePath).exists()) {
ImageData imageData = ImageDataFactory.create(imagePath);
Image img = new Image(imageData);
img.setWidth(300);
img.setHeight(200);
img.setHorizontalAlignment(HorizontalAlignment.CENTER);
document.add(img);
document.add(new Paragraph("图1:从文件加载的图片")
.setFont(chineseFont)
.setFontSize(10)
.setTextAlignment(TextAlignment.CENTER)
.setMarginBottom(20));
}
// 方式2:动态生成图片(Java2D)
BufferedImage chart = createBarChart();
String tempImagePath = "temp_chart.png";
ImageIO.write(chart, "png", new java.io.File(tempImagePath));
ImageData chartData = ImageDataFactory.create(tempImagePath);
Image chartImg = new Image(chartData);
chartImg.setWidth(400);
chartImg.setHeight(300);
chartImg.setHorizontalAlignment(HorizontalAlignment.CENTER);
document.add(chartImg);
document.add(new Paragraph("图2:动态生成的柱状图")
.setFont(chineseFont)
.setFontSize(10)
.setTextAlignment(TextAlignment.CENTER));
document.close();
// 清理临时文件
new java.io.File(tempImagePath).delete();
System.out.println("带图片的PDF生成成功!");
}
private static BufferedImage createBarChart() {
int width = 800;
int height = 600;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 设置背景
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// 绘制标题
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Arial", Font.BOLD, 24));
g2d.drawString("年度销售统计", 300, 50);
// 数据
int[] values = {120, 150, 180, 160, 200, 250};
String[] labels = {"1月", "2月", "3月", "4月", "5月", "6月"};
Color[] colors = {
new Color(255, 99, 132),
new Color(54, 162, 235),
new Color(255, 206, 86),
new Color(75, 192, 192),
new Color(153, 102, 255),
new Color(255, 159, 64)
};
int barWidth = 80;
int startX = 100;
int startY = height - 100;
int chartHeight = 400;
// 绘制柱状图
for (int i = 0; i < values.length; i++) {
int barHeight = (int)((double)values[i] / 300 * chartHeight);
int x = startX + i * (barWidth + 40);
int y = startY - barHeight;
g2d.setColor(colors[i]);
g2d.fillRect(x, y, barWidth, barHeight);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Arial", Font.PLAIN, 16));
g2d.drawString(labels[i], x + 20, startY + 30);
g2d.drawString(String.valueOf(values[i]), x + 20, y - 10);
}
// 绘制坐标轴
g2d.setColor(Color.BLACK);
g2d.drawLine(startX - 50, startY, width - 100, startY);
g2d.drawLine(startX - 50, 50, startX - 50, startY);
g2d.dispose();
return image;
}
}
主方法测试
public class PdfGeneratorTest {
public static void main(String[] args) {
try {
// 测试1:简单PDF
String simplePdf = "D:/pdf/simple.pdf";
SimplePdfGenerator.generateSimplePdf(simplePdf);
// 测试2:带样式的PDF
String styledPdf = "D:/pdf/styled.pdf";
StyledPdfGenerator.generateStyledPdf(styledPdf);
// 测试3:表格PDF
String tablePdf = "D:/pdf/employee_table.pdf";
TablePdfGenerator.generateEmployeeTablePdf(tablePdf);
// 测试4:带图片的PDF
String imagePdf = "D:/pdf/with_image.pdf";
ImagePdfGenerator.generateImagePdf(imagePdf);
System.out.println("所有PDF生成成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
PDF合并案例(实用工具)
import com.itextpdf.kernel.pdf.*;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
public class PdfMerger {
public static void mergePdfs(List<String> srcFiles, String destFile)
throws Exception {
PdfWriter writer = new PdfWriter(new FileOutputStream(destFile));
PdfDocument mergedDoc = new PdfDocument(writer);
for (String srcFile : srcFiles) {
PdfReader reader = new PdfReader(srcFile);
PdfDocument srcDoc = new PdfDocument(reader);
// 复制页面
int pages = srcDoc.getNumberOfPages();
for (int i = 1; i <= pages; i++) {
srcDoc.copyPagesTo(i, i, mergedDoc);
}
srcDoc.close();
}
mergedDoc.close();
System.out.println("PDF合并成功!");
}
}
使用建议
-
选择合适的库:
- iText:功能最强大,适合复杂需求
- PDFBox:Apache出品,开源免费
- OpenPDF:iText 5的分支,更开源
-
中文字体处理:
- 使用
font-asian依赖 - 指定中文字体如
STSong-Light - 注意字体嵌入以避免显示问题
- 使用
-
性能优化:
- 复用字体对象
- 批量处理大数据
- 及时关闭资源
这个教程涵盖了Java生成PDF的主要应用场景,根据实际需求,您可以调整样式、布局和功能,如有特殊需求(如添加水印、加密等),可以进一步扩展。