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());
              }
          }
      }
相关推荐
小张快跑。19 小时前
Maven指定版本下载以及相关配置
java·maven
zhishidi19 小时前
Spring @Scheduled注解调度机制详解
java·python·spring
⑩-19 小时前
Blocked与Wati的区别
java·开发语言
AAA简单玩转程序设计19 小时前
救命!Java这3个小技巧,写起来爽到飞起✨
java
IManiy19 小时前
Java表达式引擎技术选型分析(SpEL、QLExpress)
java·开发语言
历程里程碑19 小时前
C++ 17异常处理:高效捕获与精准修复
java·c语言·开发语言·jvm·c++
雨雨雨雨雨别下啦19 小时前
ssm复习总结
java·开发语言
qq_3561969519 小时前
Day 43图像数据与显存机制@浙大疏锦行
python
yaoh.wang19 小时前
力扣(LeetCode) 94: 二叉树的中序遍历 - 解法思路
python·算法·leetcode·面试·职场和发展·二叉树·跳槽
摸鱼仙人~19 小时前
Flask-SocketIO 连接超时问题排查与解决(WSL / 虚拟机场景)
后端·python·flask