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());
              }
          }
      }
相关推荐
AI瓦力8 分钟前
技术分享 | 彻底解决图片“躺平”问题:Java 后端强制校准图片方向
java
武子康11 分钟前
Java-219 RocketMQ Spring Boot 集成指南:生产者与消费者实战
java·spring boot·分布式·kafka·消息队列·rocketmq·java-rocketmq
我星期八休息12 分钟前
Linux系统编程—库制作与原理
linux·运维·服务器·数据结构·人工智能·python·散列表
RainCityLucky15 分钟前
Java Swing 自定义组件库分享(七)
java·笔记·后端
Cloud_Shy61819 分钟前
Python 数据分析基础入门:《Excel Python:飞速搞定数据分析与处理》学习笔记系列(第十二章 用户定义函数 上篇)
python·数据分析·excel·pandas
小白|28 分钟前
cmake:昇腾CANN构建系统完全指南
java·c++·算法
weixin_5129761733 分钟前
Java 面试宝典 Beta5.0
java
BU摆烂会噶33 分钟前
【LangGraph】House_Agent 实战(四):预定流程 —— 中断与人工干预
android·人工智能·python·langchain
AI玫瑰助手34 分钟前
Python运算符:比较运算符(等于不等等于大于小于)与返回值
android·开发语言·python
Ting-yu35 分钟前
Spring AI Alibaba零基础速成(5) ---- Memory(记忆)
java·人工智能·后端·spring