本文目录导读:

我来详细介绍Java生成PDF的几种主流方法及具体案例。
iText库(最常用)
Maven依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
基础案例:创建简单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.Table;
public class SimplePdfGenerator {
public static void createSimplePdf(String dest) throws Exception {
// 1. 创建PdfWriter
PdfWriter writer = new PdfWriter(dest);
// 2. 创建PdfDocument
PdfDocument pdfDoc = new PdfDocument(writer);
// 3. 创建Document
Document document = new Document(pdfDoc);
// 4. 添加内容
document.add(new Paragraph("Hello World!"));
document.add(new Paragraph("这是中文PDF示例"));
// 5. 关闭文档
document.close();
}
public static void main(String[] args) throws Exception {
createSimplePdf("simple.pdf");
System.out.println("PDF生成成功!");
}
}
高级案例:表格和样式
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
public class AdvancedPdfGenerator {
public static void createTablePdf(String dest) throws Exception {
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 添加中文标题
document.add(new Paragraph("员工信息表")
.setTextAlignment(TextAlignment.CENTER)
.setFontSize(20)
.setBold());
// 创建表格
float[] columnWidths = {1, 2, 3, 2};
Table table = new Table(UnitValue.createPercentArray(columnWidths));
// 添加表头
String[] headers = {"ID", "姓名", "部门", "薪资"};
for (String header : headers) {
Cell cell = new Cell().add(new Paragraph(header))
.setBackgroundColor(ColorConstants.LIGHT_GRAY)
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
// 添加数据
String[][] data = {
{"001", "张三", "技术部", "15000"},
{"002", "李四", "市场部", "12000"},
{"003", "王五", "人事部", "10000"}
};
for (String[] row : data) {
for (String cellData : row) {
table.addCell(new Cell().add(new Paragraph(cellData))
.setTextAlignment(TextAlignment.CENTER));
}
}
document.add(table);
document.close();
}
}
Apache POI(适用于简单PDF)
Maven依赖
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
案例:使用PDFBox创建PDF
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
public class PdfBoxExample {
public static void createPdf() throws Exception {
try (PDDocument document = new PDDocument()) {
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
// 设置字体
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 24);
contentStream.beginText();
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello PDFBox!");
contentStream.endText();
contentStream.close();
document.save("pdfbox-example.pdf");
}
}
}
JasperReports(报表生成)
Maven依赖
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.20.5</version>
</dependency>
案例:从数据生成PDF报表
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import java.util.*;
public class JasperReportExample {
public static void generateReport() throws JRException {
// 准备数据
List<Employee> employees = Arrays.asList(
new Employee("001", "张三", "技术部"),
new Employee("002", "李四", "市场部")
);
// 创建数据源
JRBeanCollectionDataSource dataSource =
new JRBeanCollectionDataSource(employees);
// 编译报表模板
JasperReport jasperReport = JasperCompileManager
.compileReport("template.jrxml");
// 填充数据
JasperPrint jasperPrint = JasperFillManager
.fillReport(jasperReport, new HashMap<>(), dataSource);
// 导出PDF
JasperExportManager.exportReportToPdfFile(
jasperPrint, "report.pdf");
}
}
class Employee {
private String id;
private String name;
private String department;
// 构造方法和getter/setter
}
使用模板引擎+HTML转PDF
Maven依赖(使用Flying Saucer)
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
案例:HTML模板转PDF
import org.xhtmlrenderer.pdf.ITextRenderer;
public class HtmlToPdfExample {
public static void convertHtmlToPdf() throws Exception {
String htmlContent = """
<html>
<head>
<style>
body { font-family: SimSun; }
h1 { color: blue; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid black; padding: 8px; }
</style>
</head>
<body>
<h1>用户信息报告</h1>
<table>
<tr><th>ID</th><th>姓名</th><th>邮箱</th></tr>
<tr><td>001</td><td>张三</td><td>zhang@example.com</td></tr>
<tr><td>002</td><td>李四</td><td>li@example.com</td></tr>
</table>
</body>
</html>
""";
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(htmlContent);
renderer.layout();
try (OutputStream os = new FileOutputStream("output.pdf")) {
renderer.createPDF(os);
}
}
}
完整实用示例:生成发票PDF
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
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.property.TextAlignment;
public class InvoicePdfGenerator {
public static void createInvoice(String fileName,
InvoiceData data) throws Exception {
PdfWriter writer = new PdfWriter(fileName);
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 公司信息
document.add(new Paragraph("XX科技有限公司")
.setTextAlignment(TextAlignment.CENTER)
.setFontSize(24).setBold());
document.add(new Paragraph("发票号码:" + data.getInvoiceNo())
.setTextAlignment(TextAlignment.RIGHT));
// 客户信息
document.add(new Paragraph("客户:" + data.getCustomerName()));
document.add(new Paragraph("日期:" + data.getDate()));
document.add(new Paragraph("\n"));
// 商品明细表格
float[] columnWidths = {1, 3, 2, 2, 2};
Table table = new Table(UnitValue.createPercentArray(columnWidths));
// 表头
String[] headers = {"序号", "商品名称", "数量", "单价", "金额"};
for (String header : headers) {
table.addHeaderCell(new Cell().add(new Paragraph(header))
.setBold().setTextAlignment(TextAlignment.CENTER));
}
// 商品数据
double total = 0;
int index = 1;
for (InvoiceItem item : data.getItems()) {
table.addCell(String.valueOf(index++));
table.addCell(item.getName());
table.addCell(String.valueOf(item.getQuantity()));
table.addCell(String.format("%.2f", item.getPrice()));
double amount = item.getQuantity() * item.getPrice();
table.addCell(String.format("%.2f", amount));
total += amount;
}
document.add(table);
// 总计
document.add(new Paragraph("\n"));
document.add(new Paragraph("总计金额:¥" + String.format("%.2f", total))
.setTextAlignment(TextAlignment.RIGHT)
.setBold().setFontSize(16));
document.close();
}
// 测试
public static void main(String[] args) throws Exception {
InvoiceData data = new InvoiceData();
data.setInvoiceNo("INV-2024-001");
data.setCustomerName("阿里巴巴集团");
data.setDate("2024-01-15");
data.setItems(Arrays.asList(
new InvoiceItem("笔记本电脑", 5, 5999.00),
new InvoiceItem("显示器", 10, 1599.00),
new InvoiceItem("键盘", 20, 299.00)
));
createInvoice("invoice.pdf", data);
System.out.println("发票PDF生成成功!");
}
}
// 数据模型
class InvoiceData {
private String invoiceNo;
private String customerName;
private String date;
private List<InvoiceItem> items;
// getter/setter省略
}
class InvoiceItem {
private String name;
private int quantity;
private double price;
// 构造方法、getter/setter省略
}
性能优化建议
// 1. 使用连接池管理字体资源
public class PdfFontProvider {
private static Map<String, PdfFont> fontCache = new HashMap<>();
public static PdfFont getFont(String fontPath) throws Exception {
return fontCache.computeIfAbsent(fontPath,
path -> PdfFontFactory.createFont(path));
}
}
// 2. 批量处理时复用资源
public class BatchPdfGenerator {
public void batchGenerate(List<Data> dataList) throws Exception {
// 预编译模板,复用PdfWriter等资源
PdfFont font = PdfFontFactory.createFont("STSong-Light");
for (Data data : dataList) {
try (PdfWriter writer = new PdfWriter(data.getFileName());
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc)) {
// 生成PDF
generateContent(document, data, font);
}
}
}
}
选型建议
| 场景 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 简单PDF | iText/iText7 | 功能强大,社区活跃 | 商业使用需授权 |
| 报表类 | JasperReports | 模板化,支持复杂报表 | 学习曲线较陡 |
| 基于HTML | Flying Saucer | 可用CSS样式 | 对CSS支持有限 |
| 官方格式 | Apache PDFBox | Apache许可证,免费 | 功能相对基础 |
| 跨平台 | Aspose.Words | 功能全面 | 商业授权费用高 |
选择合适的方案时,考虑以下因素:
- 预算:商业使用要注意许可证
- 复杂度:简单文档用iText,复杂报表用JasperReports
- 团队技能:熟悉HTML可选HTML转PDF方式
- 性能要求:大数据量时选择性能更好的方案
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播