excel导出实例

技术方案 最大记录数 内存占用特点
SSF(2003) 65,536 全内存操作,易溢出
XSSF(2007) 1,048,576 全内存操作,大文件仍会溢出
SXSSF(POI3.8+) 无硬性限制 通过临时文件缓存数据
  1. 基础XSSF导出(适合小数据量)

    java 复制代码
    public 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流式导出(适合大数据量)

    java 复制代码
    public 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格式导出(最高性能方案)

    java 复制代码
    public 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);
          }
      }
    • 工具类

      java 复制代码
      import 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());
              }
          }
      }
相关推荐
期待のcode10 小时前
认识Java虚拟机
java·开发语言·jvm
vyuvyucd10 小时前
Qwen-1.8B-Chat昇腾Atlas800TA2部署实战
python
raining_peidx10 小时前
xxljob源码
java·开发语言
肥猪猪爸10 小时前
双重检查锁(DCL)与 volatile 的关键作用
java·开发语言·单例模式
轻竹办公PPT10 小时前
2026 年工作计划 PPT 内容拆解,对比不同 AI 生成思路
人工智能·python·powerpoint
yaoxin52112310 小时前
289. Java Stream API - 从字符串的字符创建 Stream
java·开发语言
浮游本尊10 小时前
Java学习第35天 - 分布式系统深入与大数据处理
java
癫狂的兔子10 小时前
【Python】【Flask】抽奖功能
开发语言·python·flask
2301_7806698610 小时前
Set集合、HashSet集合的底层原理
java
linuxxx11010 小时前
python变量引用的小案例
python