pdf文件生成

在Java中开发发票导出PDF功能,有多种成熟可靠的方式。下面我将为你介绍几种主流的实现方案,并提供选择建议。

特性/库iTextApache PDFBoxJasperReports
​主要优势​功能全面,API丰富,支持复杂文档(文本、图片、表格、表单、水印、加密等)Apache开源项目,专注于PDF处理和内容提取,支持创建、修改和提取文本、图片强大的报表生成引擎,基于模板设计,支持多种数据源,特别适合复杂、格式固定的报表
​许可协议​​AGPL(开源),商业用途需购买许可​Apache License 2.0 (完全免费)Eclipse Public License
​最佳适用场景​需要高质量、复杂布局的PDF,如精密报表、发票、合同需要处理现有PDF、提取内容或进行基础生成,且要求完全免费开源的场景基于数据生成结构化报表,如业务报表、图表,且希望模板与代码分离
​学习曲线​较陡峭适中适中(需学习模板设计工具)

📌 准备工作:添加 Maven 依赖

根据你的选择,在 pom.xml 中添加相应依赖。

​iText:​

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version> <!-- 请以最新版本为准 -->
</dependency>

​Apache PDFBox:​

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version> <!-- 请以最新版本为准 -->
</dependency>

​JasperReports:​

<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>6.17.0</version> <!-- 请以最新版本为准 -->
</dependency>

🧾 实现方式一:使用 iText

iText 功能强大,适合创建布局精确的发票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;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import java.io.FileNotFoundException;

public class ITextInvoiceExample {

    public static void main(String[] args) {
        String dest = "invoice_itext.pdf";
        try {
            PdfWriter writer = new PdfWriter(dest);
            PdfDocument pdfDoc = new PdfDocument(writer);
            Document doc = new Document(pdfDoc);

            // 1. 添加发票标题
            doc.add(new Paragraph("增值税电子发票")
                    .setTextAlignment(TextAlignment.CENTER)
                    .setBold().setFontSize(16));

            // 2. 添加基本信息表格
            Table infoTable = new Table(UnitValue.createPercentArray(new float[]{1, 2, 1, 2}));
            infoTable.setWidth(UnitValue.createPercentValue(100));
            
            infoTable.addCell("发票号码");
            infoTable.addCell("INV-2025-0918-001");
            infoTable.addCell("开票日期");
            infoTable.addCell("2025年9月18日");
            
            infoTable.addCell("销售方");
            infoTable.addCell("某某科技有限公司");
            infoTable.addCell("购买方");
            infoTable.addCell("某某有限公司");
            
            doc.add(infoTable);

            // 3. 添加商品明细表格(示例)
            Table itemTable = new Table(UnitValue.createPercentArray(new float[]{3, 2, 2, 2, 2}));
            itemTable.setWidth(UnitValue.createPercentValue(100));
            
            // 表头
            itemTable.addHeaderCell("商品名称");
            itemTable.addHeaderCell("规格型号");
            itemTable.addHeaderCell("单位");
            itemTable.addHeaderCell("数量");
            itemTable.addHeaderCell("金额");
            
            // 表格内容
            itemTable.addCell("软件开发服务");
            itemTable.addCell("标准");
            itemTable.addCell("项");
            itemTable.addCell("1");
            itemTable.addCell("¥1000.00");
            
            doc.add(itemTable);

            // 4. 添加合计金额、备注等
            doc.add(new Paragraph("合计金额:人民币壹仟元整").setBold());
            doc.add(new Paragraph("备注:请按时支付"));
            
            doc.close();
            System.out.println("iText发票PDF生成成功!");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

🧾 实现方式二:使用 Apache PDFBox

Apache PDFBox 是Apache的开源项目,适合基础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.PDType1Font;
import java.io.IOException;

public class PDFBoxInvoiceExample {

    public static void main(String[] args) {
        try (PDDocument document = new PDDocument()) {
            PDPage page = new PDPage();
            document.addPage(page);

            try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                
                // 设置字体和起始位置
                contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
                contentStream.beginText();
                contentStream.newLineAtOffset(100, 700);
                
                // 添加发票标题
                contentStream.showText("增值税电子发票 - Apache PDFBox生成");
                contentStream.newLineAtOffset(0, -30); // 下移30单位
                
                // 添加基本信息
                contentStream.setFont(PDType1Font.HELVETICA, 12);
                contentStream.showText("发票号码: INV-2025-0918-002");
                contentStream.newLineAtOffset(0, -20);
                contentStream.showText("开票日期: 2025年9月18日");
                contentStream.newLineAtOffset(0, -20);
                contentStream.showText("销售方: 某某科技有限公司");
                contentStream.newLineAtOffset(0, -20);
                contentStream.showText("购买方: 某某有限公司");
                contentStream.newLineAtOffset(0, -30);
                
                // 可以继续添加商品明细、金额等信息...
                contentStream.showText("商品: 软件开发服务 | 数量: 1 | 金额: ¥1000.00");
                contentStream.newLineAtOffset(0, -20);
                contentStream.showText("合计金额:人民币壹仟元整");
                
                contentStream.endText();
            }

            document.save("invoice_pdfbox.pdf");
            System.out.println("PDFBox发票PDF生成成功!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🧾 实现方式三:使用 JasperReports

JasperReports 基于模板生成报表,适合数据可视化。​​首先需要用 JasperSoft Studio 设计报表模板 (.jrxml 文件)​​,定义好发票的布局、字段、样式等。

import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JasperReportsInvoiceExample {

    public static void main(String[] args) {
        try {
            // 0. 编译报表模板 (.jrxml -> .jasper)
            // JasperCompileManager.compileReportToFile("invoice_template.jrxml"); // 通常可预先编译或运行时编译
            // 本例假设已编译好,直接加载
            JasperReport jasperReport = JasperCompileManager.compileReport("path/to/invoice_template.jrxml");

            // 1. 准备报表参数(如固定信息、统计值等)
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("INVOICE_TITLE", "增值税电子发票");
            parameters.put("SELLER_NAME", "某某科技有限公司");
            parameters.put("BUYER_NAME", "某某有限公司");
            parameters.put("CURRENT_DATE", "2025年9月18日");

            // 2. 准备数据源(如商品明细列表,通常来自数据库查询或业务逻辑)
            List<Map<String, Object>> invoiceItems = new ArrayList<>();
            Map<String, Object> item1 = new HashMap<>();
            item1.put("productName", "软件开发服务");
            item1.put("spec", "标准");
            item1.put("quantity", 1);
            item1.put("unitPrice", 1000.00);
            item1.put("totalAmount", 1000.00);
            invoiceItems.add(item1);
            // ... 可以添加更多商品项
            JRBeanCollectionDataSource itemsDataSource = new JRBeanCollectionDataSource(invoiceItems);
            parameters.put("ItemDataSource", itemsDataSource); // 通常模板中会定义这个数据源

            // 3. 填充报表
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());

            // 4. 导出为PDF
            JasperExportManager.exportReportToPdfFile(jasperPrint, "invoice_jasper.pdf");
            
            System.out.println("JasperReports发票PDF生成成功!");

        } catch (JRException e) {
            e.printStackTrace();
        }
    }
}

💡 选择建议和注意事项

  1. ​如何选择?​

    • 需要创建​​复杂布局和样式​​(如发票、合同)且​​预算充足​​ → 考虑 ​​iText​​。
    • 项目要求​​完全开源免费​​,或需​​处理现有PDF​​(如提取文本、合并拆分) → 选择 ​​Apache PDFBox​​。
    • 需生成​​数据驱动的、格式固定的报表​​(如每日销售报告、员工花名册) → 选择 ​​JasperReports​​。
  2. ​通用注意事项​

    • ​中文支持​​:确保使用支持中文的字体(如SimSun、SimHei),并将字体文件嵌入PDF或在系统中可用,防止乱码。
    • ​布局精确性​​:发票对格式要求高,建议使用​​表格​​或​​绝对坐标​​来精确定位元素。
    • ​数据安全​​:涉及敏感信息的发票,应考虑使用库提供的功能对PDF进行​​加密​​或​​数字签名​​。
    • ​性能​​:大批量生成时,注意管理资源(如及时关闭文档流)。
    • ​模板化​​:对于发票这类格式固定的文档,​​强烈建议​​采用模板方式(如JasperReports或自行设计模板机制),将布局设计与代码分离,便于维护和修改。

希望这些详细的方案和代码示例能帮助你顺利实现发票导出PDF的功能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tqs_12345

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值