网站投票页面怎么做,form e哪个网站做,互联网家装平台有哪些,新手小白如何互联网创业1、概述
我们都知道Excel可以分为早期的Excel2003版本#xff08;使用POI的HSSF对象操作#xff09;和Excel2007版本#xff08;使用POI的XSSF操作#xff09;#xff0c;两者对百万数据的支持如下#xff1a; Excel 2003#xff1a;在POI中使用HSSF对象时#…1、概述
我们都知道Excel可以分为早期的Excel2003版本使用POI的HSSF对象操作和Excel2007版本使用POI的XSSF操作两者对百万数据的支持如下 Excel 2003在POI中使用HSSF对象时excel 2003最多只允许存储65536条数据一般用来处理较少的数据量。这时对于百万级别数据Excel肯定容纳不了。 Excel 2007当POI升级到XSSF对象时它可以直接支持excel2007以上版本因为它采用ooxml格式。这时excel可以支持1048576条数据单个sheet表就支持近百万条数据。但实际运行时还可能存在问题原因是执行POI报表所产生的行对象单元格对象字体对象他们都不会销毁这就导致OOM的风险。
2、解决方案分析
对于百万数据量的Excel导入导出只讨论基于Excel2007的解决方法。在ApachePoi 官方提供了对操作大数据量的导入导出的工具和解决办法操作Excel2007使用XSSF对象可以分为三种模式
java代码解析xml
dom4j:一次性加载xml文件再解析
SAX:逐行加载逐行解析
用户模式 用户模式有许多封装好的方法操作简单但创建太多的对象非常耗内存之前使用的方法
事件模式 基于SAX方式解析XMLSAX全称Simple API for XML它是一个接口也是一个软件包。它是一种XML解析的替代方法不同于DOM解析XML文档时把所有内容一次性加载到内存中的方式它逐行扫描文档一边扫描一边解析。
SXSSF对象是用来生成海量excel数据文件主要原理是借助临时存储空间生成excel
3、原理分析
在实例化SXSSFWorkBook这个对象时可以指定在内存中所产生的POI导出相关对象的数量默认100一旦内存中的对象的个数达到这个指定值时就将内存中的这些对象的内容写入到磁盘中XML的文件格式就可以将这些对象从内存中销毁以后只要达到这个值就会以类似的处理方式处理直至Excel导出完成。
4、百万数据的导出
4.1、模拟数据
第一步、创建表
CREATE TABLE tb_user2 (id bigint(20) NOT NULL COMMENT 用户ID,user_name varchar(100) DEFAULT NULL COMMENT 姓名,phone varchar(15) DEFAULT NULL COMMENT 手机号,province varchar(50) DEFAULT NULL COMMENT 省份,city varchar(50) DEFAULT NULL COMMENT 城市,salary int(10) DEFAULT NULL,hire_date datetime DEFAULT NULL COMMENT 入职日期,dept_id bigint(20) DEFAULT NULL COMMENT 部门编号,birthday datetime DEFAULT NULL COMMENT 出生日期,photo varchar(200) DEFAULT NULL COMMENT 照片路径,address varchar(300) DEFAULT NULL COMMENT 现在住址
) ENGINEInnoDB DEFAULT CHARSETutf8;
2、创建存储过程
DELIMITER $$ -- 重新定义“;”分号
DROP PROCEDURE IF EXISTS test_insert $$ -- 如果有test_insert这个存储过程就删除
CREATE PROCEDURE test_insert() -- 创建存储过程BEGINDECLARE n int DEFAULT 1; -- 定义变量n1SET AUTOCOMMIT0; -- 取消自动提交while n 5000000 do INSERT INTO tb_user2 VALUES ( n, CONCAT(测试, n), 13800000001, 北京市, 北京市, 11000, 2001-03-01 21:18:29, 1, 1981-03-02 00:00:00, \\static\\user_photos\\1.jpg, 北京市西城区宣武大街1号院);SET nn1;END while;COMMIT;
END $$
3、开始执行
CALL test_insert();插入500W数据大概需要200至300秒左右
4.2、思路分析
导出时使用的是SXSSFWorkBook这个类一个工作表sheet最多只能放1048576行数据 当我们的业务数据已超过100万了一个sheet就不够用了必须拆分到多个工作表。
导出百万数据时有两个弊端
1、不能使用模板
2、不能使用太多的样式
也就是说导出的数据太多时必须要放弃一些。
4.3、代码实现
UserController代码
GetMapping(value /downLoadMillion,name 导出用户百万数据的导出)
public void downLoadMillion(Long id,HttpServletRequest request,HttpServletResponse response) throws Exception{userService.downLoadMillion(request,response);
}UserService代码
public void downLoadMillion(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 创建一个空的工作薄Workbook workbook new SXSSFWorkbook();int page 1;int pageSize200000;int rowIndex 1; //每一个工作页的行数int num 0; //总数据量Row row null;Cell cell null;Sheet sheet null;while (true){ //不停地查询ListUser userList this.findPage(page,pageSize);if(CollectionUtils.isEmpty(userList)){ //如果查询不到就不再查询了break;}if(num%10000000){ //每100W个就重新创建新的sheet和标题rowIndex 1;// 在工作薄中创建一个工作表sheet workbook.createSheet(第((num/1000000)1)个工作表);
// 设置列宽sheet.setColumnWidth(0,8*256);sheet.setColumnWidth(1,12*256);sheet.setColumnWidth(2,15*256);sheet.setColumnWidth(3,15*256);sheet.setColumnWidth(4,30*256);// 处理标题String[] titles new String[]{编号,姓名,手机号,入职日期,现住址};// 创建标题行Row titleRow sheet.createRow(0);for (int i 0; i titles.length; i) {cell titleRow.createCell(i);cell.setCellValue(titles[i]);}}// 处理内容for (User user : userList) {row sheet.createRow(rowIndex);cell row.createCell(0);cell.setCellValue(user.getId());cell row.createCell(1);cell.setCellValue(user.getUserName());cell row.createCell(2);cell.setCellValue(user.getPhone());cell row.createCell(3);cell.setCellValue(simpleDateFormat.format(user.getHireDate()));cell row.createCell(4);cell.setCellValue(user.getAddress());rowIndex;num;}page;// 继续查询下一页}
// 导出的文件名称String filename百万数据.xlsx;
// 设置文件的打开方式和mime类型ServletOutputStream outputStream response.getOutputStream();response.setHeader( Content-Disposition, attachment;filename new String(filename.getBytes(),ISO8859-1));response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet);workbook.write(outputStream);}4.4、测试结果
导出的这个文档大概需要3-5分钟的时间有105 MB内容如下
注意使用附件的形式下载前端访问必须通过window.open(),否则附件可能无法下载。