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());
              }
          }
      }
相关推荐
老欧学视觉42 分钟前
ubuntu20.04系统下安装SlowFast行为检测项目并跑通训练
python·深度学习·计算机视觉
p***q781 小时前
SpringBoot实战:高效实现API限流策略
java·spring boot·后端
3***16101 小时前
【JavaEE】Spring Boot 项目创建
java·spring boot·java-ee
6***v4171 小时前
VScode 开发 Springboot 程序
java·spring boot·后端
t***31651 小时前
SpringBoot中自定义Starter
java·spring boot·后端
橘子编程1 小时前
经典排序算法全解析
java·算法·排序算法
z***3351 小时前
SpringBoot获取bean的几种方式
java·spring boot·后端
aloha_7892 小时前
联易融测开面试准备
java·python·面试·单元测试
s***46982 小时前
【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)
java·spring boot·后端