当前位置: 首页 > 工具软件 > J-Excel > 使用案例 >

JAVA 操作Excel之三剑客:JXL、POI、EasyExcel

燕实
2023-12-01

三剑客:JXL、POI、EasyExcel

  • JXL
  • POI
  • EasyExcel

JXL 读写Excel

# 写入
WritableWorkbook cw = Workbook.createWorkbook(new File("E:\\test\\test02.xls"));
WritableSheet sheet1 = cw.createSheet("第一页", 0);
for (int i = 1; i <= 9; i++) {
	Label label = new Label(i, i, (i + "*" + i + "=" + i * i));
	sheet1.addCell(label);
}
cw.write();
cw.close();


# 读取
File f1 = new File("E:\\test\\test01.xls"); // jxl不支持xlsx类型的文件
Workbook workbook = Workbook.getWorkbook(f1);
Sheet sheet = workbook.getSheet(0);
Cell cell = sheet.getCell(0, 0);
String contents = cell.getContents();
System.out.println(contents);

POI 读写Excel

基本功能:

  • HSSF:提供读写Excel03格式的功能
  • XSSF:提供读写Excel07 OOXML格式
  • HWPF:读写Word HSLF:读写PPT
  • HDGF:读写Visio

HSSF

缺点: 最多只能处理65535行,超出则抛出异常

优点: 一次性加载到缓存,不操作磁盘,最后一次性写入磁盘,速度快。

XSSF

缺点: 写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条(OOM)

优点: 可以写较大的数据量,如20万条

SXSSF

优点: 可以写非常大的数据量,如100万条甚至更多,写数据速度快,占用更少的内存。

注意: 过程中会产生临时文件,需要清理临时文件

# POI 写数据
// 1. 创建一个工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
// 2. 创建工作表
HSSFSheet sheet = workbook.createSheet("第一页");
// 3. 创建行
HSSFRow row1 = sheet.createRow(0);
// 4. 创建一个单元格(0,0)
HSSFCell cell1 = row1.createCell(0);
cell1.setCellValue("aaa");

// (0,1)
HSSFCell cell2 = row1.createCell(1);
cell2.setCellValue("bbb");

// 第二行
HSSFRow row2 = sheet.createRow(1);
HSSFCell createCell1 = row2.createCell(0);
long currentTimeMillis = System.currentTimeMillis();
createCell1.setCellValue("当前时间:");
HSSFCell createCell2 = row2.createCell(1);
createCell2.setCellValue(currentTimeMillis);

// 生成一张表(IO流)03版本就是使用xls结尾!
FileOutputStream fos = new FileOutputStream("E:\\test\\test03.xls");
workbook.write(fos);

fos.close();
workbook.close();

# POI 读数据
public void readData() throws IOException {
	// 创建 FileInputStream 输入流
	FileInputStream fis = new FileInputStream("E:\\test\\test02.xls");
	// 创建一个 workbook 对象
	HSSFWorkbook workbook = new HSSFWorkbook(fis);
	// 获取第一个表
	HSSFSheet sheet = workbook.getSheetAt(0);
	// 获取第一行
	HSSFRow row = sheet.getRow(0);
	// 获取第一个单元格
	HSSFCell cell = row.getCell(0);

	// 读取值的时候,一定要注意数据类型
	// System.out.println(cell.getStringCellValue()); // 只能获取String类型的值
	// System.out.println(cell.getNumericCellValue()); // 只能获取数字类型的值

	fis.close();
}

练习一: HSSFWrokbook VS XSSFWrokbook 写入65535行数据性能测试

#  HSSFWrokbook VS XSSFWrokbook 存取65535行数据,需要的时间
# HSSFWrokbook
long begin = System.currentTimeMillis();
HSSFWorkbook workbook = new HSSFWorkbook();
// XSSFWorkbook workbook = new XSSFWorkbook();

HSSFSheet sheet = workbook.createSheet();
for (int i = 0; i < 65536; i++) {
	HSSFRow row = sheet.createRow(i);
	for (int j = 0; j < 10; j++) {
		HSSFCell cell = row.createCell(j);
		cell.setCellValue(j);
	}
}

FileOutputStream fos = new FileOutputStream("E:\\test\\test044.xlsx");
workbook.write(fos);
long end = System.currentTimeMillis();

long useTime = (end - begin) / 1000;
System.out.println("耗用了:" + useTime + "秒");

workbook.close();
fos.close();


# XSSFWrokbook
long begin = System.currentTimeMillis();
// HSSFWorkbook workbook = new HSSFWorkbook();
XSSFWorkbook workbook = new XSSFWorkbook();

XSSFSheet sheet = workbook.createSheet();
for (int i = 0; i < 65536; i++) {
	XSSFRow row = sheet.createRow(i);
	for (int j = 0; j < 10; j++) {
		XSSFCell cell = row.createCell(j);
		cell.setCellValue(j);
	}
}

FileOutputStream fos = new FileOutputStream("E:\\test\\test044.xlsx");
workbook.write(fos);
long end = System.currentTimeMillis();

long useTime = (end - begin) / 1000;
System.out.println("耗用了:" + useTime + "秒");

workbook.close();
fos.close();

# 结果
HSSFWrokbook 耗用 1s
XSSFWrokbook 耗用 4s

练习二:XSSFWrokbook VS SXSSFWrokbook 写入10万条数据性能测试

# XSSFWrokbook
public void wBigData() throws IOException {
	long begin = System.currentTimeMillis();
	XSSFWorkbook workbook = new XSSFWorkbook();
	XSSFSheet sheet = workbook.createSheet();
	for (int i = 0; i < 100000; i++) {
		XSSFRow row = sheet.createRow(i);
		for (int j = 0; j < 5; j++) {
			XSSFCell cell = row.createCell(j);
			cell.setCellValue(j);
		}
	}

	FileOutputStream fos = new FileOutputStream("E:\\test\\test05.xlsx");
	workbook.write(fos);

	workbook.close();
	fos.close();
	long end = System.currentTimeMillis();
	long useTime = (end - begin) / 1000;
	System.out.println("耗用了:" + useTime + "秒");
}


# SXSSFWrokbook
public void wBigData() throws IOException {
	long begin = System.currentTimeMillis();
	// 创建 SXSSFWorkboo k对象
	SXSSFWorkbook workbook = new SXSSFWorkbook();
	SXSSFSheet sheet = workbook.createSheet();
	for (int i = 0; i < 100000; i++) {
		SXSSFRow row = sheet.createRow(i);
		for (int j = 0; j < 5; j++) {
			SXSSFCell cell = row.createCell(j);
			cell.setCellValue(j);
		}
	}

	FileOutputStream fos = new FileOutputStream("E:\\test\\test06.xlsx");
	workbook.write(fos);

	// 清除临时文件
	workbook.dispose();
	fos.close();
	long end = System.currentTimeMillis();
	long useTime = (end - begin) / 1000;
	System.out.println("耗用了:" + useTime + "秒");
}


# 结果
XSSFWrokbook 耗用4s
SXSSFWrokbook 耗用1s

EasyExcel 读写Excel

重写了 POI 对07版 Excel 的解析,再大的 Exce l都不会出现内存溢出。

EasyExcel 操作Excel

总结

  1. JXL: 消耗内存,会出现OOM
  2. POI: 可以一定程度上解决OOM的问题,但POI内存消耗依然很大。
  3. EasyExcel: 不会出现内存溢出。
 类似资料: