| 技术方案 | 最大记录数 | 内存占用特点 |
|---|---|---|
| SSF(2003) | 65,536 | 全内存操作,易溢出 |
| XSSF(2007) | 1,048,576 | 全内存操作,大文件仍会溢出 |
| SXSSF(POI3.8+) | 无硬性限制 | 通过临时文件缓存数据 |
-
基础XSSF导出(适合小数据量)
javapublic class BasicExcelExport { public static void export(HttpServletResponse response, Map<String, Object[]> data, String fileName) throws IOException { XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet("Sheet1"); // 填充数据 Set<String> keys = data.keySet(); int rowNum = 0; for (String key : keys) { Row row = sheet.createRow(rowNum++); Object[] objArr = data.get(key); for (int i = 0; i < objArr.length; i++) { Cell cell = row.createCell(i); cell.setCellValue(objArr[i].toString()); } } // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); // 输出流 workbook.write(response.getOutputStream()); workbook.close(); } }
-
SXSSF流式导出(适合大数据量)
javapublic class BigDataExcelExport { public static void exportLargeData(HttpServletResponse response, List<Map<String, Object>> dataList, String fileName) throws IOException { // 设置内存中保留1000行,超出部分写入临时文件 SXSSFWorkbook workbook = new SXSSFWorkbook(1000); Sheet sheet = workbook.createSheet("Data"); // 表头 Row headerRow = sheet.createRow(0); Set<String> keys = dataList.get(0).keySet(); int colNum = 0; for (String key : keys) { headerRow.createCell(colNum++).setCellValue(key); } // 数据行 int rowNum = 1; for (Map<String, Object> data : dataList) { Row row = sheet.createRow(rowNum++); colNum = 0; for (String key : keys) { row.createCell(colNum++).setCellValue(data.get(key).toString()); } } // 输出 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); workbook.write(response.getOutputStream()); workbook.dispose(); // 清理临时文件 } } -
CSV格式导出(最高性能方案)
javapublic class CsvExport { public static void exportToCsv(HttpServletResponse response, List<String[]> dataLines, String fileName) throws IOException { // 设置响应头 response.setContentType("text/csv"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); // 使用try-with-resources自动关闭流 try (PrintWriter writer = response.getWriter()) { // 写入CSV内容 for (String[] line : dataLines) { writer.println(String.join(",", line)); } } } } -
代码封装
-
业务调用
java@GetMapping("/exportMemberExcle") public void exportMemberExcle(HttpServletResponse response) { String fileName = "会员数据.xlsx"; String sheetName = "会员列表"; // 列宽配置(单位:字符数) int[] columnWidths = {20, 30, 20}; // 构建数据(TreeMap自动排序) Map<String, Object[]> data = new TreeMap<>(); data.put("1", new Object[]{"会员ID", "手机号", "注册时间"}); // 表头 // 模拟数据填充(实际应从数据库获取) List<Member> members = memberService.getAllMembers(); int rowNum = 2; for (Member member : members) { data.put(String.valueOf(rowNum++), new Object[]{ member.getId(), member.getPhone(), member.getRegisterTime() }); } try { ExportExcel.generateExcel(response, data, fileName, sheetName, columnWidths); } catch (IOException e) { log.error("导出失败", e); } } -
工具类
javaimport org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.util.Map; import java.util.Set; public class ExportExcel { public static void generateExcel(HttpServletResponse response, Map<String, Object[]> data, String fileName, String sheetName, int[] columnWidths) throws IOException { // 创建工作簿和工作表 XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(sheetName); // 设置列宽(单位:字符数*256) for (int i = 0; i < columnWidths.length; ++i) { sheet.setColumnWidth(i, columnWidths[i] * 256); } // 填充数据 Set<String> keyset = data.keySet(); int rownum = 0; for (String key : keyset) { Row row = sheet.createRow(rownum++); Object[] objArr = data.get(key); int cellnum = 0; for (Object obj : objArr) { Cell cell = row.createCell(cellnum++); setCellValue(obj, cell); // 类型安全设置单元格值 } } // 设置响应头(解决中文文件名乱码) fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1"); response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); // 流式输出 OutputStream ouputStream = response.getOutputStream(); workbook.write(ouputStream); ouputStream.flush(); ouputStream.close(); } private static void setCellValue(Object obj, Cell cell) { if (obj instanceof String) { cell.setCellValue((String) obj); } else if (obj instanceof Integer) { cell.setCellValue((Integer) obj); } else if (obj instanceof BigDecimal) { cell.setCellValue(obj.toString()); } } }
-