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

  • 相关阅读:
    RHEL5.8配置开机自动挂载磁盘
    RHEL5.8配置NFS服务
    Linux环境下Oracle数据库启动停止命令
    使用的组件:Layui
    使用的组件:Jcrop
    使用的组件:ckeditor
    使用的组件:Web Uploader
    WebSphere试用过期问题处理
    webpack学习笔记(一)
    如何用node命令和webpack命令传递参数 转载
  • 原文地址:https://www.cnblogs.com/oldboyooxx/p/9637897.html
Copyright © 2011-2022 走看看