Java中对Excel文件的解析

前言

在应用程序的开发中,经常要使用Execl文件来进行数据的倒入或导出。所以,在通过java语言实现此类需求的时候,往往会面临着Excel文件的解析(导入)或生成(导出)。在java技术生态圈中,可以进行Excel文件处理的主流技术包括:Apache POI,JXL、Alibaba EasyExcel等。

XSSF解析Excel文件

Workbook(Excel文件)

Workbook接口代表一个Excel文件,用于创建或加载(解析)Excel文件。常见实现类是XSSFWorkbook。

创建Excel文件

public class Workexecise {
	public static void main(String[] args) {
		try (Workbook workBook = new XSSFWorkbook();
				FileOutputStream out = new FileOutputStream("C:\\Users\\admin\\Desktop\\data.xlsx")) {
			Sheet sheet = workBook.createSheet();// 创建Sheet工作簿
			Row row = sheet.createRow(0);// 创建行
			Cell cell = row.createCell(0);// 创建单元格
			cell.setCellValue("序号");
			workBook.write(out);// 将内容写入Excel文件
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

创建工作簿:

// 按照默认名称创建工作簿
Sheet sheet1 = workbook.createSheet();

// 按照自定义名称创建工作簿
Sheet sheet2 = workbook.createSheet("自定义工作簿2");

 创建数据行:

Row row = sheet.createRow(0);

创建单元格:

Cell cell0 = row.createCell(0);

设置单元格:

cell0.setCellValue(UUID.randomUUID().toString());

解析Excel文件: 

public class Workexecise {
	public static void main(String[] args) {

		try (FileInputStream in = new FileInputStream("C:\\Users\\admin\\Desktop\\data.xlsx");
				Workbook workBook = new XSSFWorkbook(in)) {
			Sheet sheet0 = workBook.getSheetAt(0);// 获取Sheet工作簿
			Row row = sheet0.getRow(0);// 获取行
			Cell cell = row.getCell(0);
			String str = cell.getStringCellValue();// 如果单元格中的数据时字符串
			double num = cell.getNumericCellValue();// 如果单元格中的数据时数字

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

获取工作簿:

// 按照工作簿下标获取Sheet
Sheet sheet01 = workbook.getSheetAt(0);

// 按照工作簿名称获取Sheet
Sheet sheet02 = workbook.getSheet("Sheet0");

 获取工作簿数量:

int n = workbook.getNumberOfSheets();

获取首行下标:

int first = sheet.getFirstRowNum();

获取尾行下标:

int last = sheet.getLastRowNum();

根据下标获取指定行:

Row row = sheet.getRow(0);

 遍历所有行:

for(Row row : sheet) {
    System.out.println(row);
}

遍历指定区域:

for (int i = 1; i <= sheet.getLastRowNum(); i++) {
    Row row = sheet.getRow(i);
    System.out.println(row);
}

 根据下标获取单元格:

Cell cell = row.getCell(1);

遍历所有单元格:

for(Cell cell : row) {
				
}

 获取单元格类型:

CellType type = cell.getCellType();

设置单元格对齐:

// 创建单元格样式
CellStyle cellStyle = workbook.createCellStyle();

//设置单元格的水平对齐类型。 此时水平居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);

// 设置单元格的垂直对齐类型。 此时垂直靠底边
cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);

 超大Excel文件读写

对超大文件的写入,如果使用XSSF会造成内存、cpu等资源占用率过高,甚至会造成内存溢出等问题。因此,有下面方法:

使用POI写入:

List<String> list = Arrays.asList("妲己","貂蝉","后羿","亚瑟","鲁班","庄周","刘禅","南霸天","安琪拉","王昭君");
		try (Workbook workBook = new SXSSFWorkbook(100);
				FileOutputStream out = new FileOutputStream("C:\\Users\\admin\\Desktop\\data.xlsx")) {

			Sheet sheet = workBook.createSheet();
			
			DataFormat dataFormat = workBook.createDataFormat();
			short dateFormatCode = dataFormat.getFormat("yyyy年MM月dd日 HH:mm:ss");
			short moneyFormatCode = dataFormat.getFormat("¥#,###");
			
			CellStyle dateCellStyle = workBook.createCellStyle();
			dateCellStyle.setDataFormat(dateFormatCode);
			CellStyle moneyCellStyle = workBook.createCellStyle();
			moneyCellStyle.setDataFormat(moneyFormatCode);
			for(int i = 0;i<100000;i++) {
				String name = "A"+i;
				Row row = sheet.createRow(i+1);
				
				Cell cell0 = row.createCell(0);
				cell0.setCellValue(String.valueOf(i+1));
				Cell cell1 = row.createCell(1);
				cell1.setCellValue(name);
				Cell cell2 = row.createCell(2);
				cell2.setCellStyle(dateCellStyle);
				cell2.setCellValue(new Date());
				
				Cell cell3 = row.createCell(3);
				cell3.setCellStyle(moneyCellStyle);
				cell3.setCellValue(Math.random()*100000);
				
			}
			workBook.write(out);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

使用SXSSFWorkbook进行写入,通过设置 SXSSFWorkbook的构造参数,可以设置每次在内存中保持的行数,当达到这个值的时候,那么会把这些数据flush到磁盘上。

使用EasyExcel读取100万条数据

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

public class Work713 {
	public static void main(String[] args) {
//		EasyExcel.write("C:\\Users\\admin\\Desktop\\AAA.xlsx",Order.class)
//		.sheet("订单列表")
//		.doWrite(data());
		
		
		List<Order> orderList = new ArrayList<Order>();
		EasyExcel.read("C:\\Users\\admin\\Desktop\\AAA.xlsx",Order.class,new AnalysisEventListener<Order>() {

			@Override
			public void doAfterAllAnalysed(AnalysisContext arg0) {
				System.out.println("Game over");
			}

			@Override
			public void invoke(Order order, AnalysisContext arg1) {
				orderList.add(order);
				
			}
			@Override
			public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
				System.out.println(headMap);
				super.invokeHeadMap(headMap, context);
			}
		}).sheet().doRead();
		for(Order order:orderList) {
			System.out.println(order);
		}

	}
	private static List<Order> data(){
		List<Order> list = new ArrayList<Order>();
		for(int i = 0;i<1000000;i++) {
			list.add(new Order());
		}
		return list;
	}
	
}

总结

借助第三方库POI对Excel文件进行解析,在解析前要了解到Excel的层层关系,例如:Excel文件包含N张工作簿,工作簿中又包含N行数据,每行又包含N个单元格。数据的读、写都是对单元格进行操作。

  • 26
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

磨剑斩秋招

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值