Excel文件解析

在此模块的学习中,我们需要一个新的开源类库---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文件

java 复制代码
try(Workbook workbook =new XSSFWorkbook();
        //输出流
        FileOutputStream fos=new FileOutputStream ("D:\\IO流        
                                             \\20240414.xlsx");
workbook.write(fos);
}catc(IOException){
    e.printStackTrace();
}

(加载)解析Excel文件

java 复制代码
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对象的获取或创建

创建工作簿

java 复制代码
//按照默认名称创建Sheet
Sheet sheet1=workbook.creatSheet();
//按照自定义名称创建Sheet
Sheet sheet2=workbook.creatSheet("自定义工作簿");

获取工作簿

java 复制代码
//按照工作簿下标获取工作簿
Sheet sheet1=workbook.getSheetAt(0);
//按照工作簿名称获取工作簿
Sheet sheet2=workbook.getSheet("Sheet0");

获取工作簿的数量

java 复制代码
int n=workbook.getNumberOfSheets();

Row(数据行)

通过Sheet来进行数据行Row对象的获取或创建

创建数据行

java 复制代码
Row row=sheet.creatRow(0);

获取首行下标、尾行下标

java 复制代码
//获取首行下标
int first=sheet.getFirstRowNum();
//获取尾行下标
int last=sheet.getLastRowNum();

根据下标获取指定行

java 复制代码
Row row=sheet.getRow(0);

遍历所有行

java 复制代码
for(Row row:sheet){
    System.out.println(row);
}

Cell单元格

通过Row来进行单元格Cell对象的获取或创建

创建单元格

java 复制代码
Cell cell0=row.creatCell(0);

设置单元格的值

java 复制代码
cell0.setCellValue("序号");

根据下标获取单元格

java 复制代码
Cell cell=row.getCell(1);

设置单元格样式

创建单元格样式

java 复制代码
CellStyle headerCellStyle=workbook.creatCellStyle();

设置单元格的水平对齐类型

java 复制代码
//水平居中
headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
//垂直靠边
headerCellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);

创建并设置字体

java 复制代码
Font font =workbook.creatFont();
//设置字体加粗
font.setBold(true);
//设置字体颜色
font.setColor(Font.COLOR_RED);
//设置字体
headerCellStyle.setFont(font);

设置单元格数据样式

java 复制代码
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文件

java 复制代码
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、基于迭代器进行的遍历

java 复制代码
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语句进行遍历

java 复制代码
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文件

java 复制代码
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();
		}
    }
}

运行后结果:

相关推荐
E-iceblue1 天前
Excel 列转行/行列转换全指南:从 4 种常见解法到 Python 批量自动化
python·excel·python库·spire.xls
Data-Miner1 天前
AI处理数据的脚本复用与逻辑复用有什么区别?哪种方式更能沉淀工作成果
数据分析·excel
福兮说2 天前
在浏览器里写一个“够用就好“的 Excel 公式求值器
前端·javascript·excel·编译原理
慧都小妮子2 天前
标签打印如何减少手工抄数?用Bartender 直连 Excel 批量打印
excel·bartender·条码打印·标签打印软件·数据驱动打印·工业打印机
SunnyDays10113 天前
Java 设置 Excel 数据验证:整数、日期、文本长度、下拉列表和时间
java·excel·数据验证·下拉列表
Metaphor6923 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
用户0332126663673 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
企业数字化笔记3 天前
固定资产Excel批量导入怎么防重复?资产编码、重复检查和错误回执
java·后端·excel
CORNERSTONE3654 天前
低代码开发有哪些应用场景?
低代码·excel·erp·mes·企业数字化
小葱炖豆腐4 天前
python绘制excel折线图
python·excel·numpy·pandas·matplotlib