在此模块的学习中,我们需要一个新的开源类库---Apahche POI开源类库。这个类库的用途是:解析并生成Excel文件(Word、ppt)。Apahche POI基于DOM方式进行解析,将文件直接加载到内存,所以速度比较快,适合Excel文件数据量不大的应用场景。
除了Apahche POI,JXL、Alibaba EasyExcel也是可以进行Excel文件处理的主流技术,但是JXL只支持Excel 2023以下的版本,所以不太常见。Alibaba EasyExcel采用逐行读取的解析模式,将每行的解析结果以观察者的模式通知处理,所以比较适合数据体量较大的Excel文件解析。
那么,什么叫Excel文件的解析呢?解析文件就是按照格式读取文件,并获取文件数据内容。
Apahche POI开源类库为我们提供了许多用于Excel文件解析的接口:
Workbook接口
Workbook接口代表一个Excel文件,用于创建或加载(解析)Excel文件,Workbook有两个实现类:
①HSSFWorkbook实现类:用于老版本的Excel文件,即以xls为扩展名的文件
②XSSFWorkbook实现类:用于新版本的Excel文件,即以xlsx为扩展名的文件
创建Excel文件
try(Workbook workbook =new XSSFWorkbook();
//输出流
FileOutputStream fos=new FileOutputStream ("D:\\IO流
\\20240414.xlsx");
workbook.write(fos);
}catc(IOException){
e.printStackTrace();
}
(加载)解析Excel文件
String path="D:\\IO流\\usa.xlsx"
//输入流
FileInputStream fis=new FileInputStream (path);
//Excel文件对象--XSSFWorkbook
Workbook workbook=new XSSFWorkbook(path);
//Excel文件对象--HSSFWorkbook
Workbook workbook=new HSSFWorkbook(fis);
Sheet(工作簿)接口
通过Workbook可以进行sheet对象的获取或创建
创建工作簿
//按照默认名称创建Sheet
Sheet sheet1=workbook.creatSheet();
//按照自定义名称创建Sheet
Sheet sheet2=workbook.creatSheet("自定义工作簿");
获取工作簿
//按照工作簿下标获取工作簿
Sheet sheet1=workbook.getSheetAt(0);
//按照工作簿名称获取工作簿
Sheet sheet2=workbook.getSheet("Sheet0");
获取工作簿的数量
int n=workbook.getNumberOfSheets();
Row(数据行)
通过Sheet来进行数据行Row对象的获取或创建
创建数据行
Row row=sheet.creatRow(0);
获取首行下标、尾行下标
//获取首行下标
int first=sheet.getFirstRowNum();
//获取尾行下标
int last=sheet.getLastRowNum();
根据下标获取指定行
Row row=sheet.getRow(0);
遍历所有行
for(Row row:sheet){
System.out.println(row);
}
Cell单元格
通过Row来进行单元格Cell对象的获取或创建
创建单元格
Cell cell0=row.creatCell(0);
设置单元格的值
cell0.setCellValue("序号");
根据下标获取单元格
Cell cell=row.getCell(1);
设置单元格样式
创建单元格样式
CellStyle headerCellStyle=workbook.creatCellStyle();
设置单元格的水平对齐类型
//水平居中
headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
//垂直靠边
headerCellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);
创建并设置字体
Font font =workbook.creatFont();
//设置字体加粗
font.setBold(true);
//设置字体颜色
font.setColor(Font.COLOR_RED);
//设置字体
headerCellStyle.setFont(font);
设置单元格数据样式
CellStyle dateCellStyle=workbook.creatCellStyle();
DataFormat fmt=workbook.creatDataFormat();
//获取想要设置的日期格式的编码值(Short类型)
short dataFmtCode=fmt.getFormat("yyyy-MM-dd HH:mm:ss");
//设置自定义日期样式的编码值
//setDataFormat(short s)
dataCellStyle.setDataFormat(dataFmtCode);
//...
//为当前行创建单元格
Cell cell1=row.creatCell(1);
//设置单元格数据样式
cell1.setCellStyle(dateCellStyle)
读取Excel文件
public class Demo01 {
public static void main(String[] args) {
readExcel("D:\\IO流\\usa.xlsx");
}
public static void readExcel(String path) {
try{
//Workbook:Excel文件
//创建workbook对象
FileInputStream fis=new FileInputStream(path);
Workbook workbook=null;
if(path.endWith(".xls")){
//HSSFWorkbook()的参数是FileInputStream
workbook=new HSSFWorkbook(fis);
}else if(path.endWith(".xlsx")){
//XSSFWorkbook()可以直接传入路径
workbook=new XSSFWorkbook(path);
}
//Sheet:工作表
//通过Workbook对象,获取Excel文件中的一个sheet类型的对象
Sheet sheet=workbook.getSheetAt(0);//按照下标获取Sheet
//Row:数据行
//根据下标获取表格的第一行
Row headRow=sheet.getRow(0);
//Cell:单元格
//获取列头中的每一个单元格
Cell cell0=headeRow.getCell(0);
Cell cell1=headRow.getCell(1);
Cell cell2=headRow.getCell(2);
Cell cell3=headRow.getCell(3);
Cell cell4=headRow.getCell(4);
//输出
System.out.println("列头:");
System.out.println(cell0);
System.out.println(cell1);
System.out.println(cell2);
System.out.println(cell3);
System.out.println(cell4);
//获取其余数据
for(int i=1;i<sheet.getLastRowNum();i++){
Row row=sheet.getRow(i);
System.out.println(row.getCell(0));
System.out.println(row.getCell(1));
System.out.println(row.getCell(2));
System.out.println(row.getCell(3));
System.out.println(row.getCell(4));
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
列头:
序号
州名
确诊人数
死亡人数
治愈人数
1
加利福尼亚
3725955.0
61216.0
1979314.0
2
德克萨斯
2867774.0
49973.0
2724371.0
3
佛罗里达
2184354.0
34626.0
1733247.0
4
纽约
2058675.0
52022.0
1409198.0
5
伊利诺伊
1309552.0
24018.0
1192489.0
6
宾夕法尼亚
1124073.0
25933.0
995438.0
7
乔治亚
1087791.0
19829.0
863047.0
遍历Excel文件
1、基于迭代器进行的遍历
public class Demo02_Iterator {
public static void main(String[] args) {
String path="D:\\IO流\\ip.xlsx";
try(Workbook workbook=new XSSFWorkbook(Path) ){
Iterator<Sheet> it=workbook.iterator();
while(it.hasNext()){
Sheet sheet=it.next();
Iterator<Row> rowIt=sheet.iterator();
while(rowIt.hasNext()) {
Row row=rowIt.next();
Iterator<Cell> cellIt=row.iterator();
while(cellIt.hasNext()){
Cell cell=cellIt.next();
}
}
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、通过foreach语句进行遍历
public class Demo02_Iterator {
public static void main(String[] args) {
String path="D:\\IO流\\ip.xlsx";
try(Workbook workbook=new XSSFWorkbook(Path) ){
for(Sheet sheet:workbook){
for(Row row:sheet){
for(Cell cell:row){
System.out.println(cell);
}
System.out.println();
}
System.out.println("------------------");
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
613.0
财务处
完颜洪烈
副科长
106403949685488507
3号教学楼
212469
13796698673
53-FB-63-8C-BC-10
192.160.178.107
255.255.254.0
192.160.178.1
614.0
保卫处
夏侯渊
副科长
100848966493129265
实验楼A
583732
13791699136
AC-79-80-05-97-AF
192.300.223.214
255.255.432.0
192.300.223.1
------------------
608.0
教务处
尹志平
书记
634296517363507777
实验楼B
417686
13745910943
5A-5F-D1-2C-93-96
192.215.42.27
255.255.251.0
192.215.42.1
609.0
财务处
朱棣
副科长
045514303996101729
图书馆楼
231609
13722015321
26-14-49-A2-31-20
192.280.101.99
255.255.317.0
192.280.101.1
------------------
创建并生成一个Excel文件
public class Demo03_creatExcel {
public static void main(String[] args) {
//创建workbook
try(Workbook workbook = new XSSFWorkbook()){
//生成Sheet电子版
Sheet sheet=workbook.creatSheet("新电子数据表");
//生成row(列头)
Row headRow=sheet.creatRow(0);
//生成单元格
Cell cell0=headRow.creatCell(0);
Cell cell1=headRow.createCell(1);
Cell cell2=headRow.createCell(2);
Cell cell3=headRow.createCell(3);
//创建单元格样式
CellStyle headCellStyle=workbook.creatCellStyle();
//水平居中
headCellStyle.setAlignment(HorizontalAlignment.CENTER);
//创建字体对象
Font headCellFont=workbook.creatFont();
//字体加粗
headCellFont.setBold(true);
//字体颜色
headCellFont.setColor(Font.COLOR_RED);
//为单元格设置字体
headCellStyle.setFont(headCellFont);
//为Cell0、cell1、cell2、cell3单元格设置数据
cell0.setCellValue("序号")
cell1.setCellValue("激活码");
cell2.setCellValue("礼品卡金额");
cell3.setCellValue("过期时间");
//为Cell0、cell1、cell2、cell3设置单元格样式
cell0.setCellStyle(headCellStyle)
cell1.setCellStyle(headCellStyle);
cell2.setCellStyle(headCellStyle)
cell3.setCellStyle(headCellStyle);
//填充数据1000行
for(int i=1;i<1000;i++) {
//设置"过期时间"格式的样式
CellStyle dateCellStyle=workbook.creatCellStyle();
dateCellStyle.setAlignment(
HorizontalAlignment.CENTER);
//获取数据格式对象
DataFormat fmt=workbook.creatDataFormat();
//获取想要设置的日期格式的编码值(Short类型)
short dataFmtCode=fmt.getFormat("yyyy-MM-dd
HH:mm:ss");
//设置自定义日期样式的编码值
//setDataFormat(short s)
dataCellStyle.setDataFormat(dataFmtCode);
//设置"金额"格式的样式
CellStyle moneyCellStyle=workbook.createCellStyle();
moneyCellStyle.setAlignment(
HorizontalAlignment.CENTER);
//获取数据格式对象
short moneyFormatCode=fmt.getFormat("$###,#");
//设置自定义货币样式的编码值
moneyCellStyle.setDataFormat(moneyFormatCode);
//创建数据行
Row row=sheet.creatRow(i);
//每个数据行生成4个单元格
Cell dataCell0=row.createCell(0);
Cell dataCell1=row.createCell(1);
Cell dataCell2=row.createCell(2);
Cell dataCell3=row.createCell(3);
//填充数据
//序号
dataCell0.setCellValue(i);
//激活码
dataCell1.setCellValue(UUID.randomUUID()
.toString().substring(0,5));
//金额
dataCell2.setCellValue(Math.random*1000);
dataCell2.setCellStyle(moneyCellStyle);
//过期时间
dataCell3.setCellValue(new Date(System.
currentTimeMillis()+1000*60*60*24*i));
dataCell3.setCellStyle(dateCellStyle);
}
//写入输出流
workbook.write(new FileOutputStream("D:\\IO流
\\20240414.xlsx"));
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行后结果: