翻了好久都没找到java 实现easyExcel动态创建sheet,那写一个。
要知道以 .xlsx结尾的excel文件每个sheet 只能写104万左右的数据量,
如果想要写入500W条数据到excel,要么分到多个sheet中,每个sheet存100w左右数据,5个sheet存储完;
要么写到五个xlsx文件中,这可能不是想要的。所以写入到同一个表格文件不同的sheet中去。
封装的easyexcel只用于写数据,只要内存和硬盘足够大,亿万条数据也不在话下,但是无实际意义吧。
另外我测试创建500个sheet 都去写数据,发现也是可以的。
目录
1.添加easyexcel依赖
2.封装easyExcel处理工具类
3.使用工具类
4.结果展示
1.添加easyexcel依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.0.5</version>
</dependency>
<!--配合插件lombok 使用-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>2.封装easyExcel处理工具类
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* 通用 excel 写操作模板
*/
public class ExcelHandler {
private List<WriteSheet> sheets; //excel的sheet集合
private String dirName; //excel存放的文件夹 默认文件夹my_excel
private static final int DEFAULT_PER_SHEET_NUM = 1000000;//默认每个sheet存储的行数
/**
* 对象创建,生成excel时,文件默认存放的文件夹"my_excel"
*/
public ExcelHandler() {
}
/**
* 对象创建,生成excel时,excel文件指定存放的文件夹,文件夹可以多级 folderName:"aa/bb/cc"
*
* @param folderName
*/
public ExcelHandler(String folderName) {
dirName = folderName;
}
/**
* 创建excel和sheet,创建时可以指定sheet 数量
*
* @param excelName
* @param clazz
* @param numSheet
* @return
* @throws Exception
*/
public ExcelWriter create(String excelName, Class clazz, int numSheet) throws Exception {
ExcelWriter excelWriter = EasyExcel.write(route(excelName), clazz.asSubclass(clazz)).build();
createSheets(numSheet);
return excelWriter;
}
/**
* 创建excel和sheet,sheet 数量默认 5, 最高可存放500W 行左右的数据,受每个sheet存放数据的限制
*
* @param excelName
* @param clazz
* @return
* @throws Exception
*/
public ExcelWriter create(String excelName, Class clazz) throws Exception {
ExcelWriter excelWriter = EasyExcel.write(route(excelName), clazz.asSubclass(clazz)).build();
createSheets(5);
return excelWriter;
}
/**
* 写数据到excel,仅使用一个sheet,不可用于百万以上数据
*
* @param excelWriter
* @param list
*/
public void write(ExcelWriter excelWriter, List list) throws Exception {
excelWriter.write(list, sheets.get(0));
}
/**
* 写数据到excel
*
* @param excelWriter
* @param list 每一次的数据
* @param resize 动态调整大小
*/
public void write(ExcelWriter excelWriter, List list, int resize) throws Exception {
int index = resize / (DEFAULT_PER_SHEET_NUM + 1);
excelWriter.write(list, sheets.get(index));
}
/**
* 写完数据关闭(finish 有关流操作),必须的操作
*
* @param excelWriter
*/
public void finish(ExcelWriter excelWriter) {
excelWriter.finish();
}
/**
* 创建指定数量的sheet
*
* @param num sheet的数量
*/
private void createSheets(int num) {
sheets = new ArrayList<>();
for (int i = 1; i <= num; i++) {
WriteSheet sheet = EasyExcel.writerSheet(i, "sheet" + i).build();
sheets.add(sheet);
}
}
/**
* 表格存放路径
*
* @param excelName
* @return
*/
private String route(String excelName) {
if (null == dirName) {
dirName = "my_excel";
}
String filePath = dirName + "/";
File fp = new File(filePath);
if (!fp.exists()) {// 目录的创建
fp.mkdirs();
}
return filePath + excelName + ".xlsx";
}
}3.使用工具类
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 用户实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ContentRowHeight(15)
@HeadRowHeight(20)
@ColumnWidth(25)
public class Data1 {
@ExcelProperty("账号")
private String account;
@ExcelProperty("密码")
private String password;
}import com.alibaba.excel.ExcelWriter;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.test00();
t.test01();
}
/**
* 模拟百万以下数据导入到excel
*/
private void test00() {
int num = 0;
ExcelHandler handler = null;
ExcelWriter excelWriter = null;
try {
//创建handler对象--参数文件夹名
handler = new ExcelHandler("test_00");
excelWriter = handler.create("记录", Data1.class);
List<Data1> list = new ArrayList<>(1024);
//方式一:一次性导出
/* for (int i = 0; i < 1000000; i++) {//总数据 100W条
num++;
list.add(new Data1("张三" + num, "123abc" + num));
}
handler.write(excelWriter, list);
*/
//方式二:分多次导出 为了降低导出过程中的内存资源,也可以这样
for (int a = 0; a < 100; a++) {//模拟拿100 次数据
for (int i = 0; i < 10000; i++) {//模拟一次拿的数据
num++;
list.add(new Data1("张三" + num, "123abc" + num));
}
handler.write(excelWriter, list);
list.clear();//必须clear,否则数据会重复
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (null != excelWriter) {
handler.finish(excelWriter);
}
}
}
/**
* 模拟百万以上数据导入到excel
*/
private void test01() {
int count = 0;
int num = 0;
ExcelHandler handler = null;
ExcelWriter excelWriter = null;
try {
//创建handler对象--参数:文件夹名
handler = new ExcelHandler("test_001");
excelWriter = handler.create("记录", Data1.class, 10);
List<Data1> list = new ArrayList<>(1024);
//此处依旧可以模仿test00()去优化
for (int t = 0; t < 10; t++) {//模拟分页页数 每页50W数据
for (int i = 0; i < 500000; i++) {//模拟每次数据量
num++;
list.add(new Data1("张三" + num, "123abc" + num));
}
//count 将控制插入哪一个sheet
count += list.size();
handler.write(excelWriter, list, count);
list.clear();//必须clear,否则数据会重复
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (null != excelWriter) {
handler.finish(excelWriter);
}
}
}
}4.结果展示

备注:1.工具适用于数据导出,百万以下数据 看test00()方法的测试,百万,千万,亿万使用 test01()方法的测试。
当然也可以修改工具类达到自己的要求。
2.如果不使用lombok插件,记得写相关的get,set,构造等方法。
















