2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > Java导出Excel百万条数据表格数据实现分页easyexcel方法和Apach POI方法

Java导出Excel百万条数据表格数据实现分页easyexcel方法和Apach POI方法

时间:2022-05-30 22:51:06

相关推荐

Java导出Excel百万条数据表格数据实现分页easyexcel方法和Apach POI方法

关闭程序的查询sql语句打印日志功能,否则速度很慢

注意: 此导出excel样式只是简单设置而已

1、创建实体类 ExcelModel 导出数据库对应实体数据列表

简单样式设计

MAVEN仓库依赖或者下载依赖jar包

<!-- /artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>

关于样式可以看源码默认值进行更改默认设置

参考一些样式 /p/481547301/weixin_47215296/article/details/126102600@Getter@Setter@ContentRowHeight(16)@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)@HeadRowHeight(30)@ColumnWidth(35)@HeadFontStyle(fontName="宋体")@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER,shrinkToFit = BooleanEnum.TRUE)public class ExcelModel {@ExcelIgnore//忽略此表头内容private Integer id;// 主键ID@ExcelProperty(value = "姓名") //表头内容private String name;// 姓名@ExcelProperty(value = "年龄")private Integer age;// age@ExcelProperty(value = "地址")private String address;// 地址@ExcelProperty(value = "性别")private String sex;// 性别@ExcelIgnoreprivate Integer pageStartIndex;//起始索引 查询索引位置@ExcelIgnoreprivate Integer pageSize;//每页数量 相当于数据库内数据步长}

1.1创建mapper接口

@Param 选择 引入 import org.apache.ibatis.annotations.Param;

Integer selecttxxxCount(@Param("model")ExcelModel model);List<ExcelModel> selectData(@Param("model")ExcelModel model);

1.2创建mapper.xml

<select id="selecttxxxCount" resultType="Integer">select *from table_name <where>动态sql筛选条件</where></select><select id="selectData" resultType="ExcelModel">select *from table_name <where>动态sql筛选条件</where><if test="model.pageStartIndex!=null and model.pageSize!=null">limit #{model.pageStartIndex},#{model.pageSize}</select>

2、创建 services 实现类

客户端是下载的作用,数据的处理是在服务器端进行的

xxxClass 类 作用接收前端传递来的对应数据参数 比如 页码、每页大小 其他筛选条件等xxxentity 类对应的实例xxxMapper 对应的mapper文件名//响应输出流在下方使用了 这个就不用了ServletOutputStream outputStream = response.getOutputStream();

2.1、方法1==》核心代码 分页写入–适应数据量百万

select * from table_name limit startIndex,step举例 select * from table_name limit 15,1000xxxentity.setPageStartIndex(i * page_size); ---对应起始索引xxxentity.setPageSize(page_size);--对应查询的记录行数

//核心代码public void exportExcelData(HttpSession session, HttpServletResponse response, xxxClass xxxentity) throws Exception {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = new String(("定义导出excel名").getBytes(), "ISO8859_1");response.setHeader("Content-disposition", "attachment; filename=" +fileName + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ".xlsx");//查询总条数List<Integer> total = xxxMapper.selecttxxxCount(xxxentity); //计算页数// 定义每个sheet数据数量int page_size = 3000;//计算将分多少页int export_pagenumber = total % page_size > 0 ? total / page_size + 1 : total / page_size;//创建输出流 ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), xxxClass.class).build();WriteSheet writeSheet = new WriteSheet();//创建工作簿for (int i = 0; i < export_pagenumber; i++) {writeSheet.setSheetName("第"+(i+1)+"页");xxxentity.setPageStartIndex(i * page_size); //某处起始索引 (固定步长行数*第几个i)xxxentity.setPageSize(page_size);//从起始索引开始对应的截取数据 step 步长行数List<xxxClass> dataList = xxxMapper.selectData(xxxentity);//每循环一次 查出的数据进行写入一个sheet 工作簿excelWriter.write(dataList,writeSheet);}//循环结束 excelWriter.finish();//整个Excel文件写数据结束response.flushBuffer();//强制刷新}

2.2、方法2==》一次性写入 --适应数量1万左右

//核心代码public void exportExcelData(HttpSession session, HttpServletResponse response, xxxClass xxxentity) throws Exception {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename="+new Date()+"defineExcelName.xlsx");//一次性查询数据List<xxxClass> dataList= xxxMapper.selectData(xxxentity);//循环结束 EasyExcel.write(response.getOutputStream(), xxxClass.class).sheet("单个sheet工作簿名称").doWrite(dataList);}

2.3、代码误区 ----其实这种方法本质是一次性写入 --错误

导致内存溢出(OOM)

List<xxxClass> datalist = new ArrayList<>();for (int i = 0; i < export_pagenumber; i++) {xxxentity.setPageStartIndex(i * page_size);xxxentity.setPageSize(page_size);List<xxxClass> list= xxxMapper.selectData(xxxentity);datalist.addAll(list.subList(0,list.size()));//将查询出的集合集中收集在datalist}EasyExcel.write(response.getOutputStream(), xxxClass.class).sheet("单个sheet工作簿名称").doWrite(dataList);

3、性能比较

4、导出excel

5、oom 内存溢出

6、sax模式

SAX解析器读取输入文档并在处理文档时将每个事件推给文档处理器(MyContentHandler)。与DOM相比,SAX解析器能提供更好的性能优势,它提供对XML文档内容的有效低级访问。SAX模型最大的优点是内存消耗小,因为整个文档无需一次加载到内存中,这使SAX解析器可以解析大于系统内存的文档。另外,你无需像在DOM中那样为所有节点创建对象。最后,SAX“推”模型可用于广播环境,能够同时注册多个ContentHandler,并行接收事件,而不是在一个管道中一个接一个地进行处理。

7、Apach POI --大数据量—写不好容易内存溢出

//核心代码public void exportExcelData(HttpSession session, HttpServletResponse response, xxxClass xxxentity) throws Exception {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = new String(("定义导出excel名").getBytes(), "ISO8859_1");response.setHeader("Content-disposition", "attachment; filename=" +fileName + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ".xlsx");//查询总条数List<Integer> total = xxxMapper.selecttxxxCount(xxxentity); //计算页数// 定义每个sheet数据数量int page_size = 3000;//计算将分多少页int export_pagenumber = total % page_size > 0 ? total / page_size + 1 : total / page_size;//创建输出流 SXSSFWorkbook wbook = new SXSSFWorkbook(1500);//1500表示1500行数据时进行写到磁盘不至于内存溢出Sheet sheet = null;for (int i = 0; i < export_pagenumber; i++) {sheet = wbook.createSheet("第"+(i+1)+"页");//新建一个sheetxxxentity.setPageStartIndex(i * page_size); //某处起始索引 (固定步长行数*第几个i)xxxentity.setPageSize(page_size);//从起始索引开始对应的截取数据 step 步长行数List<xxxClass> dataList = xxxMapper.selectData(xxxentity);//每循环一次 查出的数据进行写入一个sheet 工作簿writeDataToExcel(sheet,dataList);}//循环结束 wbook.write(response.getOutputStream());//写出数据到输出流wbook.dispose();}private int currRow = 0;private void writeDataToExcel(Sheet sheet ,List<xxxClass> xxxentityList){for( int j=0;j<xxxentityList.size();j++){Row row = sheet.createRow(currRow++);int k = 0;row.createCell(k++).setCellValue(xxxentity.get(j).getId());row.createCell(k++).setCellValue(xxxentity.get(j).getUserName());row.createCell(k++).setCellValue(xxxentity.get(j).getAge());}}

8 当一个sheet数据量大于100000百万行数据进行分工作簿

@SneakyThrows(IOException.class)@ApiOperation(value = "xxxx记录导出")@PostMapping("/xxxxxx")public void exporportEasyExcel(HttpServletResponse response,@RequestBody xxxClass xxxentity) {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = new String(("定义导出excel名").getBytes(), "ISO8859_1");response.setHeader("Content-disposition", "attachment; filename=" +fileName + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ".xlsx");List<xxxClass > total = xxxMapper.pageExcel(xxxentity);int sheet_max_row = 4;int pageNumber = 0;int writeCount = 0;int step = 2;int export_pagenumber = total.size() % step > 0 ? total.size() / step + 1 : total.size() / step;ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(),xxxClass.class).build();WriteSheet writeSheet = new WriteSheet();for (int i = 0; i < export_pagenumber; i++) {xxxentity.setPageStartIndex(i * step);xxxentity.setPageSize(step);List<xxxClass> dataList = xxxMapper.pageExcel(xxxentity);writeCount += dataList.size();if (writeCount > sheet_max_row*pageNumber){pageNumber++;writeSheet.setSheetName("xxx记录"+pageNumber+"页");}excelWriter.write(dataList,writeSheet);}excelWriter.finish();response.flushBuffer();}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。