Java生成PDF案例

wen java案例 6

本文目录导读:

Java生成PDF案例

  1. Maven依赖配置
  2. 基础PDF生成案例
  3. 带样式的PDF生成(含中文支持)
  4. 生成PDF表格案例
  5. 带图片和图表的PDF
  6. 主方法测试
  7. PDF合并案例(实用工具)
  8. 使用建议

我将为您提供几个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合并成功!");
    }
}

使用建议

  1. 选择合适的库

    • iText:功能最强大,适合复杂需求
    • PDFBox:Apache出品,开源免费
    • OpenPDF:iText 5的分支,更开源
  2. 中文字体处理

    • 使用 font-asian 依赖
    • 指定中文字体如 STSong-Light
    • 注意字体嵌入以避免显示问题
  3. 性能优化

    • 复用字体对象
    • 批量处理大数据
    • 及时关闭资源

这个教程涵盖了Java生成PDF的主要应用场景,根据实际需求,您可以调整样式、布局和功能,如有特殊需求(如添加水印、加密等),可以进一步扩展。

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