当前位置:   article > 正文

Java大批量Excel读取解决方案_java读取excel文件 高性能

java读取excel文件 高性能

我们在读取excel过程中,通常使用的方案为POI的普通读取,但是遇到大数据量excel (比如一个excel超过20M,上10万行上百列等),此时一般代码会报内存溢出(OOM);

以下为一种解决方案(亲测有效):

首先引入的依赖:

  1. <!--大批量excel导入依赖开始-->
  2. <dependency>
  3. <groupId>org.apache.poi</groupId>
  4. <artifactId>poi</artifactId>
  5. <version>4.0.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.poi</groupId>
  9. <artifactId>poi-scratchpad</artifactId>
  10. <version>4.0.0</version>
  11. </dependency>
  12. <!-- 读取大量excel数据时使用 -->
  13. <dependency>
  14. <groupId>com.monitorjbl</groupId>
  15. <artifactId>xlsx-streamer</artifactId>
  16. <version>2.1.0</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.apache.poi</groupId>
  20. <artifactId>poi-ooxml</artifactId>
  21. <version>4.0.0</version>
  22. </dependency>
  23. <!--大批量excel导入依赖结束-->

Java代码:

  1. /**
  2. * 大批量数据读取 15W以上
  3. * 思路:采用分段缓存,防止出现OOM的情况
  4. * 格式限制:必须使用xlsx的格式,调用前需判断格式
  5. */
  6. public static List<Map<String,Object>> readBigExcel(MultipartFile file,String rowname,int stasheetNum,int starowNum,int stacolumn)throws Exception{
  7. //定义返回值
  8. List<Map<String,Object>> resultList=new ArrayList<Map<String,Object>>();
  9. InputStream inputStream=file.getInputStream();
  10. try( Workbook wk= StreamingReader.builder()
  11. .rowCacheSize(100) //缓存到内存中的行数,默认是10
  12. .bufferSize(4096) //读取资源时,缓存到内存的字节大小,默认是1024
  13. .open(inputStream); ){ //打开资源,必须,可以是InputStream或者是File,注意:只能打开XLSX格式的文件
  14. Sheet sheet = wk.getSheetAt(stasheetNum);
  15. String[] rownameSplit=rowname.split(",");
  16. int columnlength=rownameSplit.length;
  17. Cell cell=null;//定义单元格
  18. //遍历所有的行()
  19. for (Row row :sheet) {
  20. //row=sheet.getRow(i);//获取当前循环的行数据(因为只缓存了部分数据,所以不能用getRow来获取)此处采用增强for循环直接获取row对象
  21. Map<String, Object> paramMap = new HashMap<String, Object>();//定义一个map做数据接收
  22. if (row.getRowNum() >= starowNum) { //从设定的行开始取值
  23. //System.out.println("开始遍历第" + row.getRowNum() + "行数据:");
  24. //对当前行逐列进行循环取值
  25. for (int j = stacolumn; j < columnlength; j++) {
  26. /**
  27. 注:MyUtil.isEmpty为工具类判空方法,可替换为自己的判空工具
  28. **/
  29. if (MyUtil.isEmpty(row)) {
  30. paramMap.put(rownameSplit[j], null);//将单元格值放入map
  31. } else {
  32. cell = row.getCell(j);//获取单元格数据
  33. if (MyUtil.isEmpty(cell) && cell.getCellType() == CellType.BLANK) {
  34. paramMap.put(rownameSplit[j], null);//将单元格值放入map
  35. } else {
  36. paramMap.put(rownameSplit[j], cell.getStringCellValue());//将单元格值放入map
  37. }
  38. }
  39. }
  40. //一行循环完成,将map存入list
  41. resultList.add(paramMap);
  42. }
  43. }
  44. }
  45. return resultList;
  46. }

参数解释:

file:前台页面传递的文件

rowname:为读取的每个列起的名字。如excel文件列为 姓名,身份证,性别 ;此处可传字符串"name,card,sex";

stasheetNum:读取的工作簿  从0开始

starowNum: 开始读取的行  从0开始

stacolumn:开始读取的列 从0开始

返回值:List<Map<String,Object>>  将读取的内容 封装为到一个list中,并以map形式存放;

可根据实际情况进行调整:

注:POI版本需4以上,excel只能读取xlsx格式;如有更好方案 欢迎留言分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/88880
推荐阅读
相关标签
  

闽ICP备14008679号