SaaS-百万数据报表导出

December 17, 2023
测试
测试
测试
测试
5 分钟阅读

4 百万数据报表导出

4.1 需求分析

使用Apache POI完成百万数据量的Excel报表导出

4.2 解决方案

4.2.1 思路分析

基于XSSFWork导出Excel报表,是通过将所有单元格对象保存到内存中,当所有的Excel单元格全部创建完成之后一次性写入到Excel并导出。当百万数据级别的Excel导出时,随着表格的不断创建,内存中对象越来越多,直至内存溢出。Apache Poi提供了SXSSFWork对象,专门用于处理大数据量Excel报表导出。

4.2.2 原理分析

在实例化SXSSFWork这个对象时,可以指定在内存中所产生的POI导出相关对象的数量(默认100),一旦内存中的对象的个数达到这个指定值时,就将内存中的这些对象的内容写入到磁盘中(XML的文件格式),就可以将这些对象从内存中销毁,以后只要达到这个值,就会以类似的处理方式处理,直至Excel导出完成。

4.3 代码实现

在原有代码的基础上替换之前的XSSFWorkbook,使用SXSSFWorkbook完成创建过程即可

//1.构造数据
        List<EmployeeReportResult> list =
userCompanyPersonalService.findByReport(companyId,month+"%");
        //2.创建工作簿
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        //3.构造sheet
        String[] titles = {"编号", "姓名", "手机","最高学历", "国家地区", "护照号", "籍贯", 
"生日", "属相","入职时间","离职类型","离职原因","离职时间"};
        Sheet sheet = workbook.createSheet();
        Row row = sheet.createRow(0);
        AtomicInteger headersAi = new AtomicInteger();
        for (String title : titles) {
            Cell cell = row.createCell(headersAi.getAndIncrement());
            cell.setCellValue(title);
       }
        AtomicInteger datasAi = new AtomicInteger(1);
         Cell cell = null;
        for(int i=0;i<10000;i++) {
            for (EmployeeReportResult report : list) {
                Row dataRow = sheet.createRow(datasAi.getAndIncrement());
                //编号
                cell = dataRow.createCell(0);
                cell.setCellValue(report.getUserId());
                //姓名
                cell = dataRow.createCell(1);
                cell.setCellValue(report.getUsername());
                //手机
                cell = dataRow.createCell(2);
                cell.setCellValue(report.getMobile());
                //最高学历
                cell = dataRow.createCell(3);
                cell.setCellValue(report.getTheHighestDegreeOfEducation());
                //国家地区
                cell = dataRow.createCell(4);
                cell.setCellValue(report.getNationalArea());
                //护照号
                cell = dataRow.createCell(5);
                cell.setCellValue(report.getPassportNo());
                //籍贯
                cell = dataRow.createCell(6);
                cell.setCellValue(report.getNativePlace());
                //生日
                cell = dataRow.createCell(7);
                cell.setCellValue(report.getBirthday());
                //属相
                cell = dataRow.createCell(8);
                cell.setCellValue(report.getZodiac());
                //入职时间
                cell = dataRow.createCell(9);
                cell.setCellValue(report.getTimeOfEntry());
                //离职类型
                cell = dataRow.createCell(10);
                cell.setCellValue(report.getTypeOfTurnover());
                //离职原因
                cell = dataRow.createCell(11);
                cell.setCellValue(report.getReasonsForLeaving());
                //离职时间
                cell = dataRow.createCell(12);
                cell.setCellValue(report.getResignationTime());
           }
       }
        String fileName = URLEncoder.encode(month+"人员信息.xlsx", "UTF-8");
        response.setContentType("application/octet-stream");
        response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1")));
        response.setHeader("filename", fileName);
        workbook.write(response.getOutputStream());

4.4 对比测试

(1)XSSFWorkbook生成百万数据报表 使用XSSFWorkbook生成Excel报表,时间较长,随着时间推移,内存占用原来越多,直至内存溢出

在这里插入图片描述
在这里插入图片描述

(2)SXSSFWorkbook生成百万数据报表 使用SXSSFWorkbook生成Excel报表,内存占用比较平缓

在这里插入图片描述
在这里插入图片描述

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多