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

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

分批次导入-方法一

先介绍我一开始的写法:

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

 package oldboy;

 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import java.io.File;
import java.io.FileInputStream; /**
* Created by peng on 18/9/12.
*/
public class ExcelDemo { public static int READ_INDEX = 10;//这里设置每次读取的行数 public static void main(String[] args) throws Exception {
testImport();
} public static void testImport() throws Exception {
boolean flag = true;
//cycleNum 循环读取次数
int cycleNum = read("/Users/peng/Desktop/20180912/111.xls", 0);
while (flag) {
if (cycleNum != 0) {
cycleNum = read("/Users/peng/Desktop/20180912/111.xls", cycleNum);
} else {
flag = false;
}
}
} /**
* 读取Excel
*
* @param localPath 文件路径
* @param cycleNum 剩余的读取次数
* @return
* @throws Exception
*/
public static int read(String localPath, int cycleNum) throws Exception {
File file = new File(localPath);
FileInputStream inputStream = new FileInputStream(file);
HSSFWorkbook book = new HSSFWorkbook(inputStream);
Sheet sheet = book.getSheetAt(0); //sheet 从0开始
Row row = sheet.getRow(0); //获取第一行
int rowEndNum = getRow(); //取得最后一行的行号
//向上取整
int cycleIndex = (int) (Math.ceil((double) rowEndNum / (double) READ_INDEX));
int cycleStartNum, cycleEndNum;
if (cycleNum == 0) {//第一次循环进来
cycleNum = cycleIndex;
cycleStartNum = 1;
if (rowEndNum > READ_INDEX) {
cycleEndNum = READ_INDEX + 1;
} else {//第一次循环如果最大行数小于设定的读取行数
cycleEndNum = rowEndNum;
}
} else {
if (cycleNum == 1) {//最后一次循环的时候
cycleStartNum = READ_INDEX * (cycleIndex - cycleNum) + 1;
cycleEndNum = rowEndNum;
} else {
cycleStartNum = READ_INDEX * (cycleIndex - cycleNum) + 1;
cycleEndNum = READ_INDEX + READ_INDEX * (cycleIndex - cycleNum) + 1;
}
}
cycleNum -= 1;
//每次循环的开始行数和结束行数
System.out.println(cycleStartNum + "=======" + cycleEndNum);
//System.out.println(rowEndNum);
for (int i = cycleStartNum; i < cycleEndNum; i++) {//跳过第一行从第二行开始循环
row = sheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) {//列循环开始,从第0列开始
Cell cell = row.getCell(j);
//ExcelUtils.getCellValue获取单元格内容,这里忽略
String cellValue = ExcelUtils.getCellValue(cell);
//System.out.print(cellValue.concat(" | "));
}
//System.out.println();
}
//返回剩余循环次数
return cycleNum;
} //这里获取Excel的真实行数
public static int getRow() {
return 47;
} }

执行结果:

分批次导入-方法二

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

 package oldboy;

 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List; /**
* Created by peng on 18/9/12.
*/
public class ExcelDemo1 { public static int READ_INDEX = 10;//这里设置每次读取的行数 public static void main(String[] args) throws Exception {
testNewImport();
} public static void testNewImport() throws Exception {
String localPath = "/Users/peng/Desktop/20180912/111.xls";
//每次读READ_INDEX的量
File file = new File(localPath);
List<List<Object>> list = new ArrayList<>();
int i = 0;
while (true) {
//如果是读到下一行为空
//每一行的list
List<Object> rowList = readRow(file, i++);
if (rowList != null) {
list.add(rowList);
} else {
System.out.println("===================退出导入=============");
System.out.println("===================保存剩下的=============" + i);
//做保存动作
list.clear();
break;
}
if (list.size() == READ_INDEX) {
//做保存动作
System.out.println("===================保存=============" + i);
list.clear();
}
}
} public static List<Object> readRow(File file, int rowNum) throws Exception {
FileInputStream inputStream = new FileInputStream(file);
HSSFWorkbook book = new HSSFWorkbook(inputStream);
Sheet sheet = book.getSheetAt(0);//sheet 从0开始
List<Object> list = new ArrayList<>();
Row row = sheet.getRow(rowNum);
if (!isRowEmpty(row)) {
for (int j = 0; j < row.getLastCellNum(); j++) {//列循环开始,从第0列开始
Cell cell = row.getCell(j);
if (cell == null) {
continue;
}
String cellValue;
if (ExcelUtils.isMergedRegion(sheet, cell)) {
cellValue = ExcelUtils.getMergedRegionValue(sheet, cell);
} else {
cellValue = ExcelUtils.getCellValue(cell);
}
list.add(cellValue);
//System.out.print(cellValue.concat(" | "));
}
//System.out.println();
} else {
return null;
} return list;
} /**
* 判断是否为空行
*
* @param row
* @return
*/
public static boolean isRowEmpty(Row row) {
if (row == null) {
return true;
}
for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
Cell cell = row.getCell(c);
if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
return false;
}
return true;
} }

运行结果:

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

java poi分批次导入Excel的更多相关文章

  1. Java将数据库数据导入EXCEL

    一般的数据库数据怎么导入excel中呢??这让人非常疑惑,今天我找到了一个方法能够实现 须要导入一个第三方包下载地址 详细内容例如以下: 里面含有指导文档,index.html里面含有怎样读取数据库文 ...

  2. poi将图片导入excel(Java代码)

    package com.fh.util;import java.awt.image.BufferedImage;  import java.io.ByteArrayOutputStream;  imp ...

  3. java的jxl技术导入Excel

    项目结构: http://www.cnblogs.com/hongten/gallery/image/112177.html 在项目中我们看到Reference Libraries中的jxl.jar包 ...

  4. 在java中实现数据导入excel表格中

    1.首先前端代码如下: 一个导出按钮:<input id="export" class="btn btn-primary" type="butt ...

  5. Java POI 3.17导出EXCEL并下载(带进度条提示)

    导出数据 共4590条 只需要 5 秒左右,性能还算可以 我们再来测试一下 50000 条的性能...

  6. java poi技术读取到数据库

    https://www.cnblogs.com/hongten/p/java_poi_excel.html java的poi技术读取Excel数据到MySQL 这篇blog是介绍java中的poi技术 ...

  7. java用XSSFWorkbook实现读写Excel

    /** * 读取Excel文件的内容 * @param inputStream excel文件,以InputStream的形式传入 * @param sheetName sheet名字 * @retu ...

  8. java的poi技术读取和导入Excel

    项目结构: http://www.cnblogs.com/hongten/gallery/image/111987.html  用到的Excel文件: http://www.cnblogs.com/h ...

  9. Java POI导入导出Excel

    1.异常java.lang.NoClassDefFoundError: org/apache/poi/UnsupportedFileFormatException 解决方法: 使用的poi的相关jar ...

随机推荐

  1. HALCON里面的一维测量。

    第一步:将图片导入, 拿到图片的名字 和窗口的句柄 第二步:创建一个测量区域.这个测量区域是一个矩形,假设他的名字叫A gen_measure_rectangle2 (TmpCtrl_Row,//输入 ...

  2. append和extend区别

    append append方法用于在列表末尾添加新的对象 它是把添加的对象当成一个整体追加到末尾 a=[1,23,436] b=[] b.append(a) print(b)""& ...

  3. python中变量的交换

    a=4 b=5 #第一种 c=0 c=a a=b b=c print('a=%d,b=%d'%(a,b)) #第二种 a=a+b b=a-b a=a-b print('a=%d,b=%d'%(a,b) ...

  4. 【Maven】在intellij里,体验Maven

    1:配置Maven 从官网下载,然后将bin目录添加到系统变量Path中, 在cmd窗口,输入mvn,有执行反馈即配置成功. 配置conf/settings.xml文件,指定仓库中心下载到本地的目录 ...

  5. Ubuntu安装samba实现文件夹共享

    因工作需要,准备在Ubuntu服务器上共享文件夹,从Windows和Mac上都可以访问共享文件. 搜了一下,决定通过samba服务实现.安装过程如下: [step1]安装samba服务 sudo ap ...

  6. [转]总结一下CSS中的定位 Position 属性

    在CSS中,Position 属性经常会用到,主要是绝对定位和相对定位,简单的使用都没有问题,尤其嵌套起来,就会有些混乱,今记录总结一下,防止久而忘之. CSS position 属性值: absol ...

  7. 前端学习笔记之ES6快速入门

    0x1 let和const let ES6新增了let命令,用于声明变量.其用法类似var,但是声明的变量只在let命令所在的代码块内有效. { let x = 10; var y = 20; } x ...

  8. DDR4中的so-dimm 和component

    so-dimm :Small Outline Dual In-line Memory Module (小型双列直插式内存模块) component:直接焊接的ddr4芯片

  9. 蓝桥杯练习——C++输出阶乘的最右边一位非零数

    #include<iostream> #include<iomanip> using namespace std; #define M 10000 #define N 1000 ...

  10. yield生成器函数

    生成器有主要有四种方法: next() 执行函数,直到遇到下一个yield为止,并返回值 send(value) 为生成器发送一个数值,next()方法就相当于send(None) close() 终 ...