1. 程式人生 > >java poi分批次導入Excel

java poi分批次導入Excel

star wim blank create 執行 adr 交流 自己 con

最近換了新工作,公司要求導入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大家自己控制一下就好了,很簡單,希望對大家有幫助,有不助的地方可以提出來交流一下,轉載註明出處,謝謝。

java poi分批次導入Excel