java poi分批次导入Excel

最近换了新工作,公司要求导入Excel要分批次导入,并且是多线程的情况下执行导入,查了很多资料,没看到比较复合的,就打算自己写一个吧,可能有不足,希望指出。

上面说到多线程,这边就不贴出代码了,具体思路就是一个导入开辟一个线程,下面主要写一下我的分批次的代码思路:

分批次导入-方法一

先介绍我一开始的写法:

通过一个(最大行数/设置读取的行数)的 余数向上取整 来控制循环次数。

 1 package oldboy;
 2 
 3 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 4 import org.apache.poi.ss.usermodel.Cell;
 5 import org.apache.poi.ss.usermodel.Row;
 6 import org.apache.poi.ss.usermodel.Sheet;
 7 
 8 import java.io.File;
 9 import java.io.FileInputStream;
10 
11 /**
12  * Created by peng on 18/9/12.
13  */
14 public class ExcelDemo {
15 
16     public static int READ_INDEX = 10;//这里设置每次读取的行数
17 
18     public static void main(String[] args) throws Exception {
19         testImport();
20     }
21 
22     public static void testImport() throws Exception {
23         boolean flag = true;
24         //cycleNum 循环读取次数
25         int cycleNum = read("/Users/peng/Desktop/20180912/111.xls", 0);
26         while (flag) {
27             if (cycleNum != 0) {
28                 cycleNum = read("/Users/peng/Desktop/20180912/111.xls", cycleNum);
29             } else {
30                 flag = false;
31             }
32         }
33     }
34 
35     /**
36      * 读取Excel
37      *
38      * @param localPath 文件路径
39      * @param cycleNum  剩余的读取次数
40      * @return
41      * @throws Exception
42      */
43     public static int read(String localPath, int cycleNum) throws Exception {
44         File file = new File(localPath);
45         FileInputStream inputStream = new FileInputStream(file);
46         HSSFWorkbook book = new HSSFWorkbook(inputStream);
47         Sheet sheet = book.getSheetAt(0); //sheet 从0开始
48         Row row = sheet.getRow(0);      //获取第一行
49         int rowEndNum = getRow();  //取得最后一行的行号
50         //向上取整
51         int cycleIndex = (int) (Math.ceil((double) rowEndNum / (double) READ_INDEX));
52         int cycleStartNum, cycleEndNum;
53         if (cycleNum == 0) {//第一次循环进来
54             cycleNum = cycleIndex;
55             cycleStartNum = 1;
56             if (rowEndNum > READ_INDEX) {
57                 cycleEndNum = READ_INDEX + 1;
58             } else {//第一次循环如果最大行数小于设定的读取行数
59                 cycleEndNum = rowEndNum;
60             }
61         } else {
62             if (cycleNum == 1) {//最后一次循环的时候
63                 cycleStartNum = READ_INDEX * (cycleIndex - cycleNum) + 1;
64                 cycleEndNum = rowEndNum;
65             } else {
66                 cycleStartNum = READ_INDEX * (cycleIndex - cycleNum) + 1;
67                 cycleEndNum = READ_INDEX + READ_INDEX * (cycleIndex - cycleNum) + 1;
68             }
69         }
70         cycleNum -= 1;
71         //每次循环的开始行数和结束行数
72         System.out.println(cycleStartNum + "=======" + cycleEndNum);
73         //System.out.println(rowEndNum);
74         for (int i = cycleStartNum; i < cycleEndNum; i++) {//跳过第一行从第二行开始循环
75             row = sheet.getRow(i);
76             for (int j = 0; j < row.getLastCellNum(); j++) {//列循环开始,从第0列开始
77                 Cell cell = row.getCell(j);
78                 //ExcelUtils.getCellValue获取单元格内容,这里忽略
79                 String cellValue = ExcelUtils.getCellValue(cell);
80                 //System.out.print(cellValue.concat("   |  "));
81             }
82             //System.out.println();
83         }
84         //返回剩余循环次数
85         return cycleNum;
86     }
87 
88     //这里获取Excel的真实行数
89     public static int getRow() {
90         return 47;
91     }
92 
93 }

执行结果:

分批次导入-方法二

这个方法是我比较推荐的,最后我也是采用这种写法,一次读一行,每次读到设定的行数就保存一次,读到空行停止。

 

 1 package oldboy;
 2 
 3 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 4 import org.apache.poi.ss.usermodel.Cell;
 5 import org.apache.poi.ss.usermodel.Row;
 6 import org.apache.poi.ss.usermodel.Sheet;
 7 
 8 import java.io.File;
 9 import java.io.FileInputStream;
10 import java.util.ArrayList;
11 import java.util.List;
12 
13 /**
14  * Created by peng on 18/9/12.
15  */
16 public class ExcelDemo1 {
17 
18     public static int READ_INDEX = 10;//这里设置每次读取的行数
19 
20     public static void main(String[] args) throws Exception {
21         testNewImport();
22     }
23 
24 
25     public static void testNewImport() throws Exception {
26         String localPath = "/Users/peng/Desktop/20180912/111.xls";
27         //每次读READ_INDEX的量
28         File file = new File(localPath);
29         List<List<Object>> list = new ArrayList<>();
30         int i = 0;
31         while (true) {
32             //如果是读到下一行为空
33             //每一行的list
34             List<Object> rowList = readRow(file, i++);
35             if (rowList != null) {
36                 list.add(rowList);
37             } else {
38                 System.out.println("===================退出导入=============");
39                 System.out.println("===================保存剩下的=============" + i);
40                 //做保存动作
41                 list.clear();
42                 break;
43             }
44             if (list.size() == READ_INDEX) {
45                 //做保存动作
46                 System.out.println("===================保存=============" + i);
47                 list.clear();
48             }
49         }
50     }
51 
52     public static List<Object> readRow(File file, int rowNum) throws Exception {
53         FileInputStream inputStream = new FileInputStream(file);
54         HSSFWorkbook book = new HSSFWorkbook(inputStream);
55         Sheet sheet = book.getSheetAt(0);//sheet 从0开始
56         List<Object> list = new ArrayList<>();
57         Row row = sheet.getRow(rowNum);
58         if (!isRowEmpty(row)) {
59             for (int j = 0; j < row.getLastCellNum(); j++) {//列循环开始,从第0列开始
60                 Cell cell = row.getCell(j);
61                 if (cell == null) {
62                     continue;
63                 }
64                 String cellValue;
65                 if (ExcelUtils.isMergedRegion(sheet, cell)) {
66                     cellValue = ExcelUtils.getMergedRegionValue(sheet, cell);
67                 } else {
68                     cellValue = ExcelUtils.getCellValue(cell);
69                 }
70                 list.add(cellValue);
71                 //System.out.print(cellValue.concat("   |  "));
72             }
73             //System.out.println();
74         } else {
75             return null;
76         }
77 
78         return list;
79     }
80 
81     /**
82      * 判断是否为空行
83      *
84      * @param row
85      * @return
86      */
87     public static boolean isRowEmpty(Row row) {
88         if (row == null) {
89             return true;
90         }
91         for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
92             Cell cell = row.getCell(c);
93             if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
94                 return false;
95         }
96         return true;
97     }
98 
99 }

运行结果:

至于为什么一个是47一个是48大家自己控制一下就好了,很简单,希望对大家有帮助,有不助的地方可以提出来交流一下,转载注明出处,谢谢。

posted @ 2018-09-12 23:12  oldboyooxx  阅读(3149)  评论(0编辑  收藏  举报