Java POI实现大批量数据导出到excel

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39207535/article/details/86532151

用JavaPOI导出Excel时,应该考虑到Excel版本及数据量的问题。针对不同的Excel版本,要采用不同的工具类。

  1. HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;一张表最大支持65536行数据,256列,也就是说一个sheet页,最多导出6w多条数据

  2. XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx;它的一张表最大支持1048576行,16384列

  3. SXSSFWorkbook:是从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的API,也就是XSSF的加强版

话不多说,上代码(demo)

jar包依赖,看官自己去官网搜一下

 

public class Test1 {
    
    public static List getUser() throws ParseException{
        List<Map<String,Object>> li = new ArrayList<>();
        SimpleDateFormat df =new SimpleDateFormat("yyyy-mm-dd");
        Map<String,Object> map=new HashMap<>();
        map.put("name", “张三”);
        map.put("phone", "15636545236");
        map.put("address", "北京市"));
        Map<String,Object> map1=new HashMap<>();
        map1.put("name", “李四”);
        map1.put("phone", "1366566566556");
        map1.put("address", "重庆市"));
        Map<String,Object> map2=new HashMap<>();
        map.put("name", “王五”);
        map.put("phone", "112365487955");
        map.put("address", "上海市"));
        
        li.add(map);
        li.add(map1);
        li.add(map2);
        return li;
    }
    
 
        //逻辑:1、创建工作簿-->2、创建工作表-->3、创建行-->4、创建表格/cell-->5、写入数据-->6、设置储存路径
    public static void main(String[] args) throws ParseException {
         List<Map<String,Object>>list = Test1.getUser();//获取数据
        //1、创建工作簿
        Workbook wb = new XSSFWorkbook();
            //1.1、设置表格的格式----居中
            CellStyle cs = wb.createCellStyle();
            cs.setAlignment(HorizontalAlignment.CENTER);
        //2.1、创建工作表
        Sheet sheet = wb.createSheet("学生信息表格");
                //2.2、合并单元格的方法
                sheet.addMergedRegion(new CellRangeAddress(4, 8, 5, 9));
        //3.1、创建行----表头行
        Row row = sheet.createRow(0);
        //4、创建格
        Cell cell = row.createCell(0);
                cell.setCellValue("姓名");
                cell.setCellStyle(cs);
            cell = row.createCell(1);
                cell.setCellValue("电话");
                cell.setCellStyle(cs);
            cell = row.createCell(2);
                cell.setCellValue("地址");
                cell.setCellStyle(cs);
        //5、写入实体数据
  
        for (int i = 0; i < list.size(); i++) {
            //3.2、创建行----内容行
            row = sheet.createRow(i+1);
            Map<String,Object> us = list.get(i);
                //第几行第几格  第一行第一格为“code”
            row.createCell(0).setCellValue(us.get("name").toString());
            row.createCell(1).setCellValue(us.get("phone").toString());
            row.createCell(2).setCellValue(us.get("address").toString());
        }
        
        //6、将文件储存到指定位置
        try {
            FileOutputStream fout = new FileOutputStream("g:\\uuu.xlsx");
            System.err.println("成功");//后台打印
            wb.write(fout);
            fout.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当导出的数据较大时(我在导出时,大概30000左右的数据),会导致系统报错:

HTTP Status 500 - Handler processing failed; nested exception is java.lang.OutOfMemoryError: GC overhead limit exceeded

也就是内存溢出

这个时候就要体现SXSSFWorkbook的重要性了

    创建工作簿的时候,加入判断

Workbook wb =null;

if(list.size()<1000){

    wb= new XSSFWorkbook();
}else{

    wb= new SXSSFWorkbook();

}

从SXSSFWorkbook官网上我们可以知道:实现“BigGridDemo”策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。您可以提供用作书面数据基础的模板工作簿。有关详细信息,请参见https://poi.apache.org/spreadsheet/how-to.html#sxssf。请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注释......仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。SXSSFWorkbook默认使用内联字符串而不是共享字符串表。这非常有效,因为没有文档内容需要保存在内存中,但也被称为制作与某些客户不兼容的文档。在启用共享字符串的情况下,文档中的所有唯一字符串必须保存在内存中。根据您的文档内容,这可能比共享字符串被禁用时使用更多的资源。在决定是否启用共享字符串之前,请仔细检查您的内存预算和兼容性需求。

猜你喜欢

转载自blog.csdn.net/weixin_39207535/article/details/86532151