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大家自己控制一下就好了,很简单,希望对大家有帮助,有不助的地方可以提出来交流一下,转载注明出处,谢谢。