PDF报表利用iText生成

wen java案例 1

本文目录导读:

PDF报表利用iText生成

  1. 环境准备
  2. 基础PDF报表生成示例
  3. 高级报表样式
  4. 复杂报表(合并单元格)
  5. 添加图片和图表
  6. 工具类封装
  7. 使用示例
  8. 注意事项

我来详细介绍如何使用iText生成PDF报表。

环境准备

Maven依赖

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
    <type>pom</type>
</dependency>
<!-- 如果需要处理中文 -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

基础PDF报表生成示例

简单报表

import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.*;
import com.itextpdf.layout.element.*;
import com.itextpdf.kernel.font.*;
import com.itextpdf.io.font.constants.StandardFonts;
import java.io.*;
public class SimpleReportGenerator {
    public void generateReport(String outputPath) throws IOException {
        // 创建PDF写入器
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);
        // 添加标题
        Paragraph title = new Paragraph("销售报表")
            .setFontSize(24)
            .setBold()
            .setTextAlignment(TextAlignment.CENTER);
        document.add(title);
        // 添加日期
        Paragraph date = new Paragraph("生成日期: " + new java.util.Date())
            .setFontSize(12)
            .setTextAlignment(TextAlignment.RIGHT);
        document.add(date);
        document.close();
    }
}

带表格的报表

public class TableReportGenerator {
    public void generateTableReport(String outputPath) throws IOException {
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);
        // 创建表格
        Table table = new Table(4); // 4列
        table.setWidth(UnitValue.createPercentValue(100));
        // 添加表头
        String[] headers = {"产品名称", "销售量", "单价", "总金额"};
        for (String header : headers) {
            Cell cell = new Cell()
                .add(new Paragraph(header).setBold())
                .setBackgroundColor(new DeviceRgb(200, 200, 200))
                .setTextAlignment(TextAlignment.CENTER);
            table.addHeaderCell(cell);
        }
        // 添加数据
        Object[][] data = {
            {"产品A", 100, 29.99, 2999.00},
            {"产品B", 50, 49.99, 2499.50},
            {"产品C", 200, 19.99, 3998.00}
        };
        for (Object[] row : data) {
            for (Object cellValue : row) {
                Cell cell = new Cell()
                    .add(new Paragraph(cellValue.toString()))
                    .setTextAlignment(TextAlignment.CENTER);
                table.addCell(cell);
            }
        }
        document.add(table);
        document.close();
    }
}

高级报表样式

带样式和颜色的报表

public class StyledReportGenerator {
    public void generateStyledReport(String outputPath) throws IOException, DocumentException {
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);
        // 设置页面边距
        document.setMargins(50, 50, 50, 50);
        // 报表标题
        Paragraph reportTitle = new Paragraph("2024年度销售分析报告")
            .setFontSize(28)
            .setBold()
            .setFontColor(new DeviceRgb(0, 51, 102))
            .setTextAlignment(TextAlignment.CENTER);
        document.add(reportTitle);
        // 分隔线
        Paragraph separator = new Paragraph(new Text("⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"))
            .setTextAlignment(TextAlignment.CENTER)
            .setFontColor(new DeviceRgb(0, 51, 102));
        document.add(separator);
        // 摘要信息
        Paragraph summary = new Paragraph()
            .add("报告摘要:\n")
            .add("• 总销售额: " + formatCurrency(1250000.50) + "\n")
            .add("• 总订单数: 15,234\n")
            .add("• 同比增长: 15.3%\n")
            .setFontSize(12)
            .setMarginTop(20);
        document.add(summary);
        // 图表数据表格
        Table dataTable = new Table(new float[]{1, 1, 1, 1});
        dataTable.setWidth(UnitValue.createPercentValue(100));
        // 表头样式
        String[][] headerData = {
            {"季度", "销售额", "目标", "完成率"}
        };
        for (String[] headerRow : headerData) {
            for (String header : headerRow) {
                Cell headerCell = new Cell()
                    .add(new Paragraph(header).setBold())
                    .setBackgroundColor(new DeviceRgb(0, 51, 102))
                    .setFontColor(DeviceRgb.WHITE)
                    .setPadding(10)
                    .setTextAlignment(TextAlignment.CENTER);
                dataTable.addHeaderCell(headerCell);
            }
        }
        // 数据行
        Object[][] reportData = {
            {"Q1", 280000.00, 300000.00, "93.3%"},
            {"Q2", 320000.00, 300000.00, "106.7%"},
            {"Q3", 350000.00, 350000.00, "100%"},
            {"Q4", 300000.50, 300000.00, "100.2%"}
        };
        for (Object[] row : reportData) {
            for (int i = 0; i < row.length; i++) {
                Cell dataCell = new Cell()
                    .add(new Paragraph(row[i].toString()))
                    .setPadding(8)
                    .setTextAlignment(TextAlignment.CENTER);
                // 交替行颜色
                if (Arrays.asList(reportData).indexOf(row) % 2 == 0) {
                    dataCell.setBackgroundColor(new DeviceRgb(240, 245, 255));
                }
                dataTable.addCell(dataCell);
            }
        }
        document.add(dataTable);
        document.close();
    }
    private String formatCurrency(double amount) {
        return String.format("¥%,.2f", amount);
    }
}

复杂报表(合并单元格)

public class ComplexReportGenerator {
    public void generateComplexReport(String outputPath) throws IOException {
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);
        // 创建复杂表格
        Table table = new Table(new float[]{2, 1, 1, 1, 1});
        table.setWidth(UnitValue.createPercentValue(100));
        // 合并单元格 - 大标题
        Cell titleCell = new Cell(1, 5) // 跨5列
            .add(new Paragraph("销售业绩总表"))
            .setBackgroundColor(new DeviceRgb(0, 102, 204))
            .setFontColor(DeviceRgb.WHITE)
            .setFontSize(16)
            .setBold()
            .setTextAlignment(TextAlignment.CENTER)
            .setPadding(15);
        table.addCell(titleCell);
        // 列头
        String[] headers = {"部门", "年初目标", "实际完成", "完成率", "排名"};
        for (String header : headers) {
            Cell headerCell = new Cell()
                .add(new Paragraph(header).setBold())
                .setBackgroundColor(new DeviceRgb(200, 220, 240))
                .setTextAlignment(TextAlignment.CENTER)
                .setPadding(10);
            table.addCell(headerCell);
        }
        // 数据行
        Object[][] departmentData = {
            {"销售一部", "500万", "520万", "104%", "1"},
            {"销售二部", "400万", "380万", "95%", "3"},
            {"销售三部", "300万", "320万", "106.7%", "2"}
        };
        for (Object[] row : departmentData) {
            for (Object cellValue : row) {
                Cell cell = new Cell()
                    .add(new Paragraph(cellValue.toString()))
                    .setTextAlignment(TextAlignment.CENTER)
                    .setPadding(8);
                table.addCell(cell);
            }
        }
        // 合并单元格 - 统计信息
        Cell totalLabel = new Cell(1, 2) // 跨2列
            .add(new Paragraph("总计"))
            .setBackgroundColor(new DeviceRgb(240, 240, 240))
            .setBold()
            .setTextAlignment(TextAlignment.CENTER)
            .setPadding(10);
        table.addCell(totalLabel);
        Cell totalValue = new Cell()
            .add(new Paragraph("1220万"))
            .setBackgroundColor(new DeviceRgb(240, 240, 240))
            .setBold()
            .setTextAlignment(TextAlignment.CENTER);
        table.addCell(totalValue);
        Cell totalRate = new Cell()
            .add(new Paragraph("101.7%"))
            .setBackgroundColor(new DeviceRgb(240, 240, 240))
            .setBold()
            .setTextAlignment(TextAlignment.CENTER);
        table.addCell(totalRate);
        Cell emptyCell = new Cell()
            .setBackgroundColor(new DeviceRgb(240, 240, 240));
        table.addCell(emptyCell);
        document.add(table);
        document.close();
    }
}

添加图片和图表

public class ReportWithImages {
    public void generateReportWithImage(String outputPath) throws IOException {
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);
        // 添加图片
        Image img = new Image(ImageDataFactory.create("logo.png"));
        img.setWidth(200);
        img.setHeight(100);
        img.setHorizontalAlignment(HorizontalAlignment.CENTER);
        document.add(img);
        // 添加柱状图(使用简单的矩形表示)
        Paragraph chartTitle = new Paragraph("月度销售趋势图")
            .setBold()
            .setFontSize(14)
            .setTextAlignment(TextAlignment.CENTER);
        document.add(chartTitle);
        // 简单数据可视化
        Table chartTable = new Table(new float[]{1, 4});
        chartTable.setWidth(UnitValue.createPercentValue(80));
        double[] salesData = {120, 150, 180, 200, 160, 190};
        String[] months = {"1月", "2月", "3月", "4月", "5月", "6月"};
        for (int i = 0; i < months.length; i++) {
            Cell monthCell = new Cell()
                .add(new Paragraph(months[i]))
                .setTextAlignment(TextAlignment.RIGHT);
            chartTable.addCell(monthCell);
            // 创建可视化条
            StringBuilder bar = new StringBuilder();
            int barLength = (int)(salesData[i] / 10);
            for (int j = 0; j < barLength; j++) {
                bar.append("█");
            }
            Cell barCell = new Cell()
                .add(new Paragraph(bar.toString() + " " + salesData[i]))
                .setFontColor(new DeviceRgb(0, 102, 204));
            chartTable.addCell(barCell);
        }
        document.add(chartTable);
        document.close();
    }
}

工具类封装

public class PDFReportUtil {
    private static final String FONT_PATH = "path/to/your/font.ttf"; // 中文字体路径
    public static Document createDocument(String outputPath) throws IOException {
        PdfWriter writer = new PdfWriter(new FileOutputStream(outputPath));
        PdfDocument pdfDoc = new PdfDocument(writer);
        Document document = new Document(pdfDoc);
        // 设置中文支持
        PdfFont font = PdfFontFactory.createFont(FONT_PATH, PdfEncodings.IDENTITY_H);
        document.setFont(font);
        return document;
    }
    public static Paragraph createTitle(String text) {
        return new Paragraph(text)
            .setFontSize(24)
            .setBold()
            .setTextAlignment(TextAlignment.CENTER)
            .setMarginBottom(20);
    }
    public static Table createDefaultTable(int columns) {
        Table table = new Table(columns);
        table.setWidth(UnitValue.createPercentValue(100));
        return table;
    }
    public static Cell createStyledCell(String text, boolean isHeader) {
        Cell cell = new Cell()
            .add(new Paragraph(text))
            .setPadding(8);
        if (isHeader) {
            cell.setBold()
                .setBackgroundColor(new DeviceRgb(70, 130, 180))
                .setFontColor(DeviceRgb.WHITE);
        }
        return cell;
    }
}

使用示例

// 完整使用示例
public class ReportDemo {
    public static void main(String[] args) {
        try {
            // 生成简单报表
            SimpleReportGenerator simpleGen = new SimpleReportGenerator();
            simpleGen.generateReport("simple_report.pdf");
            // 生成表格报表
            TableReportGenerator tableGen = new TableReportGenerator();
            tableGen.generateTableReport("table_report.pdf");
            // 生成样式报表
            StyledReportGenerator styledGen = new StyledReportGenerator();
            styledGen.generateStyledReport("styled_report.pdf");
            System.out.println("PDF报表生成成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意事项

  1. 中文支持: 使用iText生成PDF时,需要添加中文字体支持
  2. 性能优化: 处理大量数据时,考虑使用分页
  3. 内存管理: 及时关闭Document和PdfDocument
  4. 布局调试: 建议使用document.setBorder()进行调试
  5. 版本兼容: 注意iText 5和iText 7的API差异

这些示例涵盖了生成PDF报表的大部分场景,可以根据实际需求进行扩展和优化。

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