当前位置:网站首页>Apache POI的读写
Apache POI的读写
2022-06-27 08:55:00 【仲夏月二十八】
POI-Excel
常用信息
- 将用户信息导出为excel表格(例如是导出数据:数据库信息)
- 将excel表中的信息录入网站数据库(例如是导入数据:题库)
开发中经常会用到excel的处理,例如导入、导出excel
操作Excel目前比较流行的就是 Apache POI 和阿里巴巴的 easyExcel
Apache POI(会比较麻烦一些)
官网:Apache POI - the Java API for Microsoft Documents
百度简介:
Apache POI [1] 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对[Microsoft Office](https://baike.baidu.com/item/Microsoft Office)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。
结构:
easyExcel(alibaba)
官网:https://github.com/alibaba/easyexce or EasyExcel · 语雀 (yuque.com)
EasyExcel 是阿里巴巴开源的一个excel处理框架,以使用简单,节约内存著称
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
文件解压文件读取通过文件形式
POI-Excel写
创建项目
创建一个新项目
引入pom依赖
<!--导入依赖--> <dependencies> <!--03--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.0</version> </dependency> <!--07--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.0</version> </dependency> <!--日期格式化工具--> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.1</version> </dependency> <!--test--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies>
科普:
03版本的execl和07版本的execl有什么区别了?
03与07版本的区别:
03版本
@Test public void test03() throws IOException { //创建一个工作簿 Workbook workbook = new HSSFWorkbook(); //创建一个工作表 Sheet sheet = workbook.createSheet("李凯的工作表"); //创建行 Row row = sheet.createRow(0); //创建单元格子((0,0) Cell cell = row.createCell(0); /*添加内容*/ cell.setCellValue("今天花费"); //(0,1) Cell cell1 = row.createCell(1); cell.setCellValue("20"); /*1,0*/ final Row row1 = sheet.createRow(1); final Cell cell2 = row1.createCell(0); cell2.setCellValue("统计时间"); final String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss:sss"); final Cell cell3 = row1.createCell(1); /*放入时间*/ cell3.setCellValue(time); /*生成一张表 03版本使用xls结尾*/ FileOutputStream fileOutputStream = new FileOutputStream(PATH + "李凯的日出消费表.xls"); workbook.write(fileOutputStream); //关闭流 fileOutputStream.close(); workbook.close(); System.out.println("生成完毕"); }
07版本
public void test07() throws IOException { //创建一个工作簿 Workbook workbook = new XSSFWorkbook(); //创建一个工作表 Sheet sheet = workbook.createSheet("李凯的工作表"); //创建行 Row row = sheet.createRow(0); //创建单元格子((0,0) Cell cell = row.createCell(0); /*添加内容*/ cell.setCellValue("今天花费"); //(0,1) Cell cell1 = row.createCell(1); cell1.setCellValue("20"); /*1,0*/ Row row1 = sheet.createRow(1); Cell cell2 = row1.createCell(0); cell2.setCellValue("统计时间"); final String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss:sss"); final Cell cell3 = row1.createCell(1); /*放入时间*/ cell3.setCellValue(time); /*生成一张表 03版本使用xls结尾*/ FileOutputStream fileOutputStream = new FileOutputStream(PATH + "李凯的日出消费表.xlsx"); workbook.write(fileOutputStream); //关闭流 fileOutputStream.close(); workbook.close(); System.out.println("生成完毕"); }
区别:
对象的区别
03版本:
Workbook workbook = new HSSFWorkbook();
07版本:
Workbook workbook = new XSSFWorkbook();
后缀名的区别
03 07 xls xlsx
03版本的大文件写入
缺点:最多只可以写入65536行
,否则会抛出异常
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快
时间:
正确代码:
public void test03BigData() throws IOException {
// 时间差:
final long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
final Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNum = 0;rowNum<65536;rowNum++){
final Row row = sheet.createRow(rowNum);
for (int cellNum = 0;cellNum<10;cellNum++){
final Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
final long end = System.currentTimeMillis();
System.out.println((double)(end-begin)/1000);
}
报错代码:
public void test03BigData() throws IOException {
// 时间差:
final long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
final Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNum = 0;rowNum<65537;rowNum++){
final Row row = sheet.createRow(rowNum);
for (int cellNum = 0;cellNum<10;cellNum++){
final Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
final long end = System.currentTimeMillis();
System.out.println((double)(end-begin)/1000);
}
07版本的大文件写入
缺点:写数据时数据速度非常慢,非常消耗内存,也会发生溢出,如100w条数据
优点:可以写比较大的数据量,如20w条数据
时间:
可以发现哪怕多了一条数据,时间就多了将进4倍
代码:
public void test07BigData() throws IOException { // 时间差: final long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new XSSFWorkbook(); //创建表 final Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNum = 0;rowNum<65537;rowNum++){ final Row row = sheet.createRow(rowNum); for (int cellNum = 0;cellNum<10;cellNum++){ final Cell cell = row.createCell(cellNum); cell.setCellValue(cellNum); } } System.out.println("over"); final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); final long end = System.currentTimeMillis(); System.out.println((double)(end-begin)/1000); }
07版本的大数据写SXSSF
优点
:可以写非常大的数据量,例如100w条数据甚至更多条,相对于07版本的XSSF,他的读写数据更快,占用内存更少注意
:过程中会产生临时文件,需要清理临时文件默认的时100条记录被保存在内存中,如果超过这个数量,则最前面的数据将会写入到临时文件当中。
如果要想自定义内存中的数据的数量,则可以通过
new SXXSFWorkbook(数量)
时间:
代码:
public void test07BigDataS() throws IOException { // 时间差: final long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new SXSSFWorkbook(); //创建表 final Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNum = 0;rowNum<65537;rowNum++){ final Row row = sheet.createRow(rowNum); for (int cellNum = 0;cellNum<10;cellNum++){ final Cell cell = row.createCell(cellNum); cell.setCellValue(cellNum); } } System.out.println("over"); final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); /*清除临时文件*/ ((SXSSFWorkbook)workbook).dispose(); final long end = System.currentTimeMillis(); System.out.println((double)(end-begin)/1000); }
POI-Excel读
07/03版本
@Test
public void test03() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xls");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new HSSFWorkbook(fileInputStream);
//获取表
final Sheet sheetAt = workbook.getSheetAt(0);
/*获取行*/
final Row row = sheetAt.getRow(0);
final int RowNum = sheetAt.getLastRowNum();
/*获取列*/
final Cell cell = row.getCell(0);
final String stringCellValue = cell.getStringCellValue();
System.out.println(stringCellValue);
System.out.println(RowNum);
fileInputStream.close();
}
07版本:
@Test
public void test03() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xlsx");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new XSSFWorkbook(fileInputStream);
//获取表
final Sheet sheetAt = workbook.getSheetAt(0);
/*获取行*/
final Row row = sheetAt.getRow(0);
final int RowNum = sheetAt.getLastRowNum();
/*获取列*/
final Cell cell = row.getCell(0);
final String stringCellValue = cell.getStringCellValue();
System.out.println(stringCellValue);
System.out.println(RowNum);
fileInputStream.close();
}
读取不同的数据类型
重点:数据转换类型!
@Test
public void test07Demo() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xlsx");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new XSSFWorkbook(fileInputStream);
//获取表
Sheet sheetAt = workbook.getSheetAt(0);
/*获取行数*/
Row row = sheetAt.getRow(0);
if (row!=null){
/*获取所有的行数*/
final int physicalNumberOfCells = row.getPhysicalNumberOfCells();
for (int CellNum = 0; CellNum < physicalNumberOfCells; CellNum++) {
final Cell cell = row.getCell(CellNum);
if (cell!=null){
/*获取行的类型*/
CellType cellType = cell.getCellType();
String stringCellValue = cell.getStringCellValue();
System.out.print(stringCellValue+" ");
}
}
System.out.println();
}
//获取表中的数据(列数)
int physicalNumberOfRows = sheetAt.getPhysicalNumberOfRows();
for (int RowNum = 1; RowNum < physicalNumberOfRows; RowNum++) {
final Row row1 = sheetAt.getRow(RowNum);
if (row1!=null){
//读取列
final int physicalNumberOfCells = row1.getPhysicalNumberOfCells();
for (int cellNumber = 0; cellNumber < physicalNumberOfCells; cellNumber++) {
final Cell cell = row1.getCell(cellNumber);
//匹配列的数据类型
if (cell!=null){
CellType cellType = cell.getCellType();
String cellValue = "";
/*判断类型*/
switch (cellType){
case STRING:
System.out.println("字符串");
cellValue= cell.getStringCellValue();
break;
case BOOLEAN:
System.out.println("布尔类型");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case BLANK:
System.out.println("为空");
break;
case NUMERIC: //数字(日期和普通数字)
if (HSSFDateUtil.isCellDateFormatted(cell)){
//日期
System.out.println("日期类型");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
}else {
System.out.println("数字");
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
case ERROR:
System.out.println("数组类型错误");
break;
}
System.out.println(cellValue);
}
}
}
}
fileInputStream.close();
}
计算公式:
@Test
public void testFormula() throws IOException {
FileInputStream fileInputStream = new FileInputStream(PATH + "Documents测试.xlsx");
Workbook workbook= new XSSFWorkbook(fileInputStream);
Sheet sheetAt = workbook.getSheetAt(0);
Row row = sheetAt.getRow(4);
Cell cell = row.getCell(0);
//拿到计算公式 eval
FormulaEvaluator xssfFormulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
//输出单元格的内容
CellType cellType = cell.getCellType();
switch (cellType){
case FORMULA: //公式
String cellFormula = cell.getCellFormula();
System.out.println(cellFormula);
//计算
CellValue evaluate = xssfFormulaEvaluator.evaluate(cell);
String CellValue = evaluate.formatAsString();
System.out.println(CellValue);
break;
}
}
边栏推荐
- Process 0, process 1, process 2
- Digital ic-1.9 understands the coding routine of state machine in communication protocol
- See how much volatile you know
- Analysis of orthofinder lineal homologous proteins and result processing
- Persistence mechanism of redis
- Code source AQS sous - jacent pour la programmation simultanée juc
- 0号进程,1号进程,2号进程
- 粗读DS-TransUNet: Dual Swin Transformer U-Net for Medical Image Segmentation
- MySQL index details
- Brief introduction to SSL encryption process
猜你喜欢
我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
C # solve the relative path problem using SQLite
this,构造器,静态,之间调用,必须搞懂啊!
经典的一道面试题,涵盖4个热点知识
IO管脚配置和pinctrl驱动
Shortcut key bug, reproducible (it seems that bug is the required function [funny.Gif])
DV scroll board width of datav rotation table component
[vivid understanding] the meanings of various evaluation indicators commonly used in deep learning TP, FP, TN, FN, IOU and accuracy
win10为任意文件添加右键菜单
Correctly understand MySQL mvcc
随机推荐
ucore lab4
Redis configuration file details
Linux下Redis的安装
ucore lab5
CLassLoader
即构「畅直播」,全链路升级的一站式直播服务
【云原生】2.3 Kubernetes 核心实战(上)
内存泄露的最直接表现
Markem Imaje Marken IMAS printer maintenance 9450e printer maintenance
Redis配置文件详解
Shortcut key bug, reproducible (it seems that bug is the required function [funny.Gif])
IO管脚配置和pinctrl驱动
I'm almost addicted to it. I can't sleep! Let a bug fuck me twice!
2022.06.26 (LC Luo 6101 Luo determines whether the matrix is an X matrix)
並發編程JUC的AQS底層源碼
Improving efficiency or increasing costs, how should developers understand pair programming?
100% understanding of 5 IO models
三道基础面试题总结
[diffusion model]
C # solve the relative path problem using SQLite