当前位置: 首页 > news >正文

JAVA Apache POI实战:从基础Excel导出入门到高级功能拓展

一、Apache POI简介

Apache POI是Apache软件基金会的开源项目,全称"Poor Obfuscation Implementation"(简陋模糊化实现),主要用于Java程序对Microsoft Office格式文件(如Excel、Word、PowerPoint等)进行读写操作。

核心组件:

  • HSSF:操作Excel 97-2003格式(.xls)
  • XSSF:操作Excel 2007+格式(.xlsx)
  • SXSSF:XSSF的流式API,适合大数据量
  • HWPF:操作Word文档
  • HSLF:操作PowerPoint

二、基础Excel导出实战

2.1 最小化示例(导出.xls)

// 创建Excel工作簿(HSSF对应.xls格式)
Workbook workbook = new HSSFWorkbook();
// 创建工作表
Sheet sheet = workbook.createSheet("员工表");// 创建表头行(第0行)
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("姓名");
headerRow.createCell(1).setCellValue("年龄");
headerRow.createCell(2).setCellValue("部门");// 添加数据行(第1行)
Row dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("张三");
dataRow.createCell(1).setCellValue(28);
dataRow.createCell(2).setCellValue("研发部");// 写入到文件
try (FileOutputStream fos = new FileOutputStream("员工表.xls")) {workbook.write(fos);
}

2.2 新版Excel导出(.xlsx)

// 使用XSSFWorkbook创建.xlsx文件
Workbook workbook = new XSSFWorkbook();
// 其余操作与HSSF完全相同

2.3 添加简单样式

// 创建单元格样式
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);                 // 加粗
headerFont.setFontHeightInPoints((short)12); // 字号
headerStyle.setFont(headerFont);
headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 背景色
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 应用样式到表头
for (int i = 0; i < headerRow.getLastCellNum(); i++) {headerRow.getCell(i).setCellStyle(headerStyle);
}

三、中级功能进阶

3.1 大数据量导出(SXSSF)

// 创建SXSSF工作簿(保留100行在内存中)
Workbook workbook = new SXSSFWorkbook(100); try {Sheet sheet = workbook.createSheet("大数据表");// 写入10万行数据for (int i = 0; i < 100000; i++) {Row row = sheet.createRow(i);row.createCell(0).setCellValue("数据" + i);row.createCell(1).setCellValue(Math.random() * 100);// 每1000行手动flush一次if (i % 1000 == 0) {((SXSSFSheet)sheet).flushRows(100); // 保留最近100行}}// 写入文件workbook.write(new FileOutputStream("大数据.xlsx"));
} finally {// 必须显式清理临时文件if (workbook instanceof SXSSFWorkbook) {((SXSSFWorkbook)workbook).dispose();}
}

3.2 合并单元格

// 合并A1到D1单元格
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));// 创建合并单元格
Row mergedRow = sheet.createRow(0);
Cell mergedCell = mergedRow.createCell(0);
mergedCell.setCellValue("季度销售报表");// 设置合并单元格样式
CellStyle mergedStyle = workbook.createCellStyle();
mergedStyle.setAlignment(HorizontalAlignment.CENTER);
mergedCell.setCellStyle(mergedStyle);

3.3 添加公式

// 添加SUM公式
Row formulaRow = sheet.createRow(sheet.getLastRowNum() + 1);
formulaRow.createCell(0).setCellValue("合计");
formulaRow.createCell(1).setCellFormula("SUM(B2:B" + (sheet.getLastRowNum()) + ")");// 强制计算公式(可选)
workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();

四、高级功能拓展

4.1 条件格式

// 创建条件格式规则
SheetConditionalFormatting scf = sheet.getSheetConditionalFormatting();// 定义格式:数值大于90显示绿色背景
ConditionalFormattingRule rule = scf.createConditionalFormattingRule("B2>90");
PatternFormatting fill = rule.createPatternFormatting();
fill.setFillBackgroundColor(IndexedColors.LIGHT_GREEN.getIndex());
fill.setFillPattern(PatternFormatting.SOLID_FOREGROUND);// 应用范围:B2到B100
CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:B100") };
scf.addConditionalFormatting(regions, rule);

4.2 数据验证(下拉列表)

// 创建数据验证约束
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(new String[]{"研发部","市场部","财务部","人事部"});// 设置验证范围(C列)
CellRangeAddressList addressList = new CellRangeAddressList(1, 100, 2, 2); // 从第2行到101行,第3列// 创建数据验证
DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
validation.setShowErrorBox(true);
sheet.addValidationData(validation);

4.3 图表生成

// 创建绘图对象
Drawing<?> drawing = sheet.createDrawingPatriarch();// 定义图表位置
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 1, 10, 15);// 创建柱状图
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.BOTTOM);// 定义数据源
BarChartData data = chart.getChartDataFactory().createBarChartData(ChartAxisFactory.createValueAxis(chart), ChartAxisFactory.createCategoryAxis(chart)
);// 设置系列数据
ChartDataSource<String> cats = DataSources.fromStringCellRange(sheet, new CellRangeAddress(1, 4, 0, 0));
ChartDataSource<Number> values = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 4, 1, 1));
data.addSeries(cats, values, "部门业绩");// 应用数据到图表
chart.plot(data);

五、实际应用技巧

5.1 性能优化建议

  1. 对象复用:重复使用CellStyle对象

    // 错误的做法:每次循环都创建新样式
    // 正确的做法:预先创建样式对象并复用
    CellStyle dataStyle = workbook.createCellStyle();
    for (Row row : sheet) {for (Cell cell : row) {cell.setCellStyle(dataStyle);}
    }
    
  2. 批量写入:使用SXSSF处理大数据

    // 设置窗口大小(内存中保留的行数)
    SXSSFWorkbook workbook = new SXSSFWorkbook(100); 
    
  3. 及时清理:处理完成后释放资源

    try {// 操作workbook...
    } finally {if (workbook instanceof SXSSFWorkbook) {((SXSSFWorkbook)workbook).dispose();}
    }
    

5.2 常见问题解决方案

问题1:导出文件损坏

  • 确保正确关闭流
  • 使用try-with-resources语句块

问题2:内存溢出

  • 对于大数据量使用SXSSF
  • 设置合理的flush间隔

问题3:日期格式问题

CellStyle dateStyle = workbook.createCellStyle();
CreationHelper createHelper = workbook.getCreationHelper();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd"));
cell.setCellValue(new Date());
cell.setCellStyle(dateStyle);

六、扩展应用场景

6.1 与Web集成(Spring Boot示例)

@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws IOException {// 设置响应头response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=export.xlsx");// 创建ExcelWorkbook workbook = new XSSFWorkbook();// ...填充数据// 写入响应流workbook.write(response.getOutputStream());workbook.close();
}

6.2 读取Excel数据

public List<Employee> readExcel(File file) throws IOException {List<Employee> employees = new ArrayList<>();try (Workbook workbook = WorkbookFactory.create(file)) {Sheet sheet = workbook.getSheetAt(0);for (Row row : sheet) {if (row.getRowNum() == 0) continue; // 跳过表头Employee emp = new Employee();emp.setName(row.getCell(0).getStringCellValue());emp.setAge((int)row.getCell(1).getNumericCellValue());emp.setDepartment(row.getCell(2).getStringCellValue());employees.add(emp);}}return employees;
}

6.3 模板导出(基于现有Excel模板)

public void exportWithTemplate() throws IOException {// 加载模板文件try (InputStream is = new FileInputStream("template.xlsx");Workbook workbook = new XSSFWorkbook(is)) {Sheet sheet = workbook.getSheetAt(0);// 在模板指定位置填充数据sheet.getRow(5).getCell(3).setCellValue("张三");sheet.getRow(6).getCell(3).setCellValue(new Date());// 保存为新文件try (FileOutputStream fos = new FileOutputStream("output.xlsx")) {workbook.write(fos);}}
}

结语

Apache POI作为Java处理Office文档的事实标准,功能强大但学习曲线适中。本文从最简单的Excel导出开始,逐步深入到大数据处理、图表生成等高级功能,最后介绍了实际项目中的最佳实践。掌握这些技能后,你可以:

  1. 轻松实现各种报表导出需求
  2. 处理百万级数据的Excel操作
  3. 创建专业的数据可视化图表
  4. 与Web应用无缝集成

建议从简单示例开始实践,逐步挑战更复杂的功能。POI的官方文档(https://poi.apache.org/)是很好的深入学习资源。

相关文章:

  • java写一个简单的冒泡排序
  • vue实例 与组件实例
  • 视频存储开源方案
  • Flutter Web 3.0革命:用WebGPU实现浏览器端实时光追渲染,性能提升300%
  • 论文分享之Prompt优化
  • C++模板与字符串:从入门到精通
  • 什么是HTTP HTTP 和 HTTPS 的区别
  • SQL进阶之旅 Day 4:子查询与临时表优化
  • vue3获取两个日期之间的所有时间
  • PostgreSQL日志管理完整方案(AI)
  • 关于Python编程语言学习的入门总结
  • SQL:合并查询(UNION)
  • .gitignore 的基本用法
  • vSphere 7.0 client 提示HTTP状态 500- 内部服务器错误
  • day021-定时任务
  • 创业团队建设与管理(一)
  • 扣子平台上如何进行对象序列化,JSON序列化和反序列化节点的使用
  • MPI实现中对消息传递的优化
  • 通用的管理账号设置设计(一)
  • 学习python day8
  • 学网站软件设计/潍坊seo按天收费
  • 今日进出沈阳最新通知/短视频seo营销系统
  • 英国零售电商网站开发/全网营销推广方式
  • 鞍山市做网站公司/成都网站排名优化公司
  • 网络游戏公司/seo主要做什么
  • 郑州哪家做网站好/seo服务是什么