Java PDF生成案例如何开发

wen java案例 24

本文目录导读:

Java PDF生成案例如何开发

  1. 常用PDF生成方案
  2. iText开发案例
  3. HTML转PDF方案(推荐)
  4. Spring Boot集成示例
  5. 最佳实践建议
  6. 常见问题解决

我来为您介绍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方式,开发效率更高。

抱歉,评论功能暂时关闭!