当前位置:首页 > 后端开发 > 正文

java怎么导出poi报表

用Java导出POI报表需引入Apache POI依赖,通过Workbook/Sheet操作单元格写入数据,设置样式后调用Write方法输出至本地/流,支持.xls/.

以下是关于 Java 使用 Apache POI 导出报表 的详细教程,涵盖核心概念、完整代码示例、最佳实践及常见问题解决方案:


技术选型与基础准备

1 为什么选择 Apache POI?

Apache POI 是 Java 操作 Microsoft Office 文档的标准库,支持以下特性:

| 组件 | 描述 | 适用场景 |

|————|——————————-|————————|

| XSSF | .xlsx (Excel 2007+) | 新项目首选 |

| HSSF | .xls (Excel 97-2003) | 兼容旧版Office |

| HWPF | Word 文档 | 复杂排版需求 |

| HSLF | PowerPoint 幻灯片 | 演示文稿自动化 |

java怎么导出poi报表 第1张

2 环境配置

Maven 依赖(推荐):

<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> <!-最新稳定版 --> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency>

️ 注意:若需支持 .xls 格式,需额外添加 poi 依赖。

java怎么导出poi报表 第2张

核心开发流程详解

1 创建 Excel 文件骨架

import org.apache.poi.ss.usermodel.; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.util.Date; public class ExcelExporter { public static void main(String[] args) throws Exception { // 1. 创建工作簿(XSSF=xlsx, HSSF=xls) Workbook workbook = new XSSFWorkbook(); // 默认生成xlsx格式 // 2. 创建工作表并命名 Sheet sheet = workbook.createSheet("销售统计"); // 3. 定义表头样式 CellStyle headerStyle = workbook.createCellStyle(); Font headerFont = workbook.createFont(); headerFont.setBold(true); // 加粗 headerFont.setColor(IndexedColors.BLACK.getIndex()); // 字体颜色 headerStyle.setFont(headerFont); // 应用字体 headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 背景色 headerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中 // 4. 写入表头数据 Row headerRow = sheet.createRow(0); // 第1行(索引从0开始) String[] headers = {"ID", "产品名称", "单价", "销量", "总金额", "下单日期"}; for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(headerStyle); // 应用样式 } // 5. 填充动态数据(模拟数据库查询结果) Object[][] data = { {1, "笔记本电脑", 5999.0, 120, 719880.0, new Date()}, {2, "智能手机", 2999.0, 350, 1049650.0, new Date()}, {3, "平板电脑", 1999.0, 80, 159920.0, new Date()} }; // 6. 数据行样式配置 CellStyle dataStyle = workbook.createCellStyle(); dataStyle.setAlignment(HorizontalAlignment.CENTER); dataStyle.setDataFormat(workbook.getCreationHelper().createDataFormat().getFormat("#,##0.00")); // 数值格式化 // 7. 遍历数据写入行 for (int rowNum = 0; rowNum < data.length; rowNum++) { Row row = sheet.createRow(rowNum + 1); // 跳过表头行 Object[] colData = data[rowNum]; for (int colNum = 0; colNum < colData.length; colNum++) { Cell cell = row.createCell(colNum); if (colData[colNum] instanceof Date) { cell.setCellValue((Date) colData[colNum]); // 设置日期格式 CellStyle dateStyle = workbook.createCellStyle(); dateStyle.cloneStyleFrom(dataStyle); dateStyle.setDataFormat(workbook.getCreationHelper().createDataFormat().getFormat("yyyy-MM-dd")); cell.setCellStyle(dateStyle); } else if (colData[colNum] instanceof Number) { cell.setCellValue((Double) colData[colNum]); cell.setCellStyle(dataStyle); // 应用数值格式 } else { cell.setCellValue(colData[colNum].toString()); } } } // 8. 自动调整列宽(根据内容自适应) for (int i = 0; i < headers.length; i++) { sheet.autoSizeColumn(i); // 逐列调整宽度 } // 9. 冻结窗格(固定表头) sheet.createFreezePane(0, 1); // 冻结首行+首列 // 10. 写入到文件系统 try (FileOutputStream outputStream = new FileOutputStream("销售报表_" + System.currentTimeMillis() + ".xlsx")) { workbook.write(outputStream); } finally { workbook.close(); // 释放资源 } } }

2 关键功能解析表

功能 实现方式 作用
单元格样式 CellStyle + Font + Color 控制字体、颜色、对齐方式等
数值格式化 DataFormat + createDataFormat() 货币/百分比/日期等专业显示
自动换行 cell.setWrapText(true) 长文本自动换行
合并单元格 sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startCol, endCol)) 跨行/列合并
插入图片 Drawing drawing = sheet.createDrawingPatriarch(); + Picture pict = drawing.addPicture(...) 嵌入公司Logo等图片
添加批注 CreationHelper helper = workbook.getCreationHelper(); Comment comment = sheet.createCellComment(cell); 单元格注释
保护工作表 sheet.protectSheet(password); 限制编辑权限


进阶技巧与最佳实践

1 大数据量处理优化

  • SXSSFEventUserModel:流式API,适合百万级数据(内存占用降低90%) import org.apache.poi.ss.util.StreamingReader; import org.apache.poi.xssf.streaming.SXSSFWorkbook;

// 创建流式工作簿(最多保留100行内存)

SXSSFWorkbook wb = new SXSSFWorkbook(100);

Sheet sh = wb.createSheet();

// …写入数据…

wb.write(outputStream); // 直接写入输出流

wb.dispose(); // 清理临时文件

分页导出:按固定行数拆分多个Sheet,避免单个文件过大。 # 3.2 动态列宽计算 ```java最大宽度调整列宽(单位:磅) for (int i = 0; i < maxColumns; i++) { sheet.trackColumnForAutoSizing(i); // 标记需要自动调整的列 sheet.autoSizeColumn(i, true); // true表示基于所有行的宽度计算 }

3 复杂表头设计

通过多层嵌套实现三级表头:

java怎么导出poi报表 第3张

// 第一层表头(大分类) Row catRow = sheet.createRow(currentRow++); catRow.createCell(0).setCellValue("电子产品"); catRow.createCell(3).setCellValue("家居用品"); // 第二层子分类(合并单元格) sheet.addMergedRegion(new CellRangeAddress(currentRow, currentRow, 0, 2)); // 合并A-C列 Row subCatRow = sheet.createRow(currentRow); subCatRow.createCell(0).setCellValue("数码设备");


典型错误及解决方案

错误现象 原因分析 解决方案
中文显示为方框 缺少中文字体包 下载微软雅黑字体文件,通过Font类加载:font.setFontName("Microsoft YaHei")
数字显示科学计数法 未设置数值格式 使用DataFormat指定格式:”#,##0.00″
文件无法打开 写入时未关闭流 确保workbook.write()后调用workbook.close()
内存溢出(OOM) 一次性加载过多数据 改用SXSSFWorkbook流式处理,或分批次写入
时间显示不正确 未设置日期格式 使用createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss")


相关问答FAQs

Q1: 导出的Excel文件中中文显示乱码怎么办?

A: 这是由于默认使用的字体不支持中文导致的,解决方法有两种:

  1. 指定中文字体:在创建Font对象时设置字体名称为系统中存在的中文字体(如”宋体”、”微软雅黑”)。 Font font = workbook.createFont(); font.setFontName("微软雅黑"); // Windows系统常用字体 font.setCharSet(FontCharSet.DEFAULT_CHARSET); // 确保字符集正确
  2. 嵌入字体文件:将TTF字体文件打包到项目中,通过InputStream加载: InputStream is = new FileInputStream("simhei.ttf"); Font font = workbook.createFont(); font.setFontName("SiHei"); // 字体名称需与文件名一致 font.setFontCharSet(FontCharSet.UTF_8); // 强制使用UTF-8编码

Q2: 如何动态设置每列的不同宽度?

A: 可以通过两种方式实现:

  1. 精确像素控制:使用sheet.setColumnWidth(columnIndex, widthUnits),其中widthUnits的单位是1/256个字符宽度。 // 设置第2列(B列)宽度为30个字符宽度 sheet.setColumnWidth(1, 30 256); // 1代表B列(索引从0开始)
  2. 自动适配内容:调用sheet.autoSizeColumn(columnIndex),该方法会根据该列中最宽的内容自动调整宽度,注意:此方法应在所有数据写入完成后调用。 // 在所有数据写入完成后调用 for (int i = 0; i < maxColumns; i++) { sheet.autoSizeColumn(i); // 逐列自动调整宽度 }

    ️ 提示:autoSizeColumn会影响性能,建议仅

0