本文目录导读:

我来为您介绍Java生成PDF文件的几种常见方案及开发案例。
常用PDF生成方案
iText - 最流行的方案
- 优点:功能强大,支持复杂布局
- 缺点:商业使用需要授权
Apache PDFBox - 开源免费
- 优点:完全开源免费
- 缺点:API相对底层
Flying Saucer + iText - HTML转PDF
- 优点:支持CSS样式,适合复杂页面
iText开发案例
Maven依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
</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. 创建PDF写入器
PdfWriter writer = new PdfWriter(dest);
// 2. 创建PDF文档
PdfDocument pdf = new PdfDocument(writer);
// 3. 创建文档对象
Document document = new Document(pdf);
// 4. 添加内容
document.add(new Paragraph("Hello World!"));
document.add(new Paragraph("这是第一个PDF文档"));
// 5. 关闭文档
document.close();
}
}
高级示例:表格和样式
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.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
public class AdvancedPdfGenerator {
public static void createInvoice(String dest) throws Exception {
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 设置字体(支持中文)
PdfFont font = PdfFontFactory.createFont("STSong-Light",
"UniGB-UCS2-H", false);
// 添加标题
Paragraph title = new Paragraph("发票明细")
.setFont(font)
.setFontSize(20)
.setTextAlignment(TextAlignment.CENTER)
.setBold();
document.add(title);
// 创建表格
float[] columnWidths = {1, 2, 1, 1};
Table table = new Table(UnitValue.createPercentArray(columnWidths));
table.setWidth(UnitValue.createPercentValue(100));
// 添加表头
String[] headers = {"序号", "商品名称", "数量", "价格"};
for (String header : headers) {
Cell cell = new Cell()
.add(new Paragraph(header).setFont(font))
.setBackgroundColor(ColorConstants.LIGHT_GRAY)
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
// 添加数据
String[][] data = {
{"1", "笔记本电脑", "2", "9,999"},
{"2", "机械键盘", "1", "599"},
{"3", "鼠标", "3", "299"}
};
for (String[] row : data) {
for (String cellValue : row) {
Cell cell = new Cell()
.add(new Paragraph(cellValue).setFont(font))
.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
}
}
document.add(table);
document.close();
}
}
HTML转PDF方案(推荐)
Maven依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
示例代码
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.FileOutputStream;
public class HtmlToPdfGenerator {
public static void convertHtmlToPdf(String htmlContent, String dest)
throws Exception {
ITextRenderer renderer = new ITextRenderer();
// 设置HTML内容
renderer.setDocumentFromString(htmlContent);
// 解析和布局
renderer.layout();
// 生成PDF
try (FileOutputStream fos = new FileOutputStream(dest)) {
renderer.createPDF(fos);
}
}
public static void main(String[] args) throws Exception {
String html = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: SimSun; }
h1 { color: #333; text-align: center; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>月度销售报告</h1>
<table>
<tr>
<th>月份</th>
<th>销售额</th>
<th>利润</th>
</tr>
<tr>
<td>一月</td>
<td>100,000</td>
<td>20,000</td>
</tr>
<tr>
<td>二月</td>
<td>120,000</td>
<td>25,000</td>
</tr>
</table>
</body>
</html>
""";
convertHtmlToPdf(html, "report.pdf");
}
}
Spring Boot集成示例
Controller层
@RestController
@RequestMapping("/api/pdf")
public class PdfController {
@Autowired
private PdfService pdfService;
@PostMapping("/generate")
public ResponseEntity<byte[]> generatePdf(@RequestBody PdfRequest request) {
try {
byte[] pdfBytes = pdfService.generateInvoicePdf(request);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDisposition(
ContentDisposition.builder("attachment")
.filename("invoice_" + request.getInvoiceNo() + ".pdf")
.build()
);
return ResponseEntity.ok()
.headers(headers)
.body(pdfBytes);
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
}
}
Service层
@Service
public class PdfService {
public byte[] generateInvoicePdf(PdfRequest request) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 生成PDF内容...
document.close();
return baos.toByteArray();
}
}
最佳实践建议
性能优化
// 使用缓存字体
private static final Map<String, PdfFont> FONT_CACHE = new ConcurrentHashMap<>();
public static PdfFont getFont(String fontName) throws Exception {
return FONT_CACHE.computeIfAbsent(fontName, name -> {
try {
return PdfFontFactory.createFont(name, "UniGB-UCS2-H", false);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
内存管理
// 大文件处理时使用流式处理
PdfWriter writer = new PdfWriter(outputStream,
new WriterProperties().setFullCompression(true));
模板设计模式
public abstract class BasePdfGenerator {
public byte[] generate() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
addHeader(document);
addContent(document);
addFooter(document);
document.close();
return baos.toByteArray();
}
protected abstract void addHeader(Document document) throws Exception;
protected abstract void addContent(Document document) throws Exception;
protected abstract void addFooter(Document document) throws Exception;
}
常见问题解决
中文显示问题
// 方案1:使用系统字体
PdfFont font = PdfFontFactory.createFont("STSong-Light",
"UniGB-UCS2-H", false);
// 方案2:使用自定义字体文件
PdfFont font = PdfFontFactory.createFont(
"path/to/chinese-font.ttf",
PdfEncodings.IDENTITY_H,
true);
分页处理
// 监听页面事件
pdf.addEventHandler(PdfDocumentEvent.END_PAGE,
new PdfPageEvent() {
@Override
public void onEndPage(PdfDocumentEvent event) {
// 处理分页逻辑
}
});
就是Java PDF生成的完整开发指南,根据您的具体需求选择合适的方案,推荐使用HTML转PDF方式,开发效率更高。