Apache POI:解决数据库和Excel之间相互转换的烦恼~
目录
- 引言
- 一、简介
- 二、POI-Excel 写
- 1、创建项目
- 2、引入依赖
- 3、步骤
- 1. 创建工作簿
- 2. 创建工作表
- 3. 创建行
- 4. 创建单元格
- 5. 单元格中填入数据
- 6. 通过IO流生成表
- 03版本完整代码
- 07版本完整代码
- 大文件写 HSSF(03)
- 大文件写 XSSF(07)
- 大文件写 SXSSF(07)
- 三、POI-Excel 读
- 03版本
- 07版本
- 不同的数据类型的读取
- 含计算公式的单元格读取
引言
开发中经常会设计到 Excel 的处理,如导出 Excel,导入Excel 到数据库中!
关于表格导入导出第三方组件工具,市面上比较知名的有两个:
- Apache 的
POI
- 阿里巴巴 的
EasyExcel
今天我们来了解了解 Apache POI
一、简介
官网: http://poi.apache.org/
结构:
- HSSF - 提供读写
Microsoft Excel
格式档案的功能。excel 2003 版本 - XSSF - 提供读写
Microsoft Excel
OOXML格式档案的功能。excel 2007 版本 - HWPF - 提供读写
Microsoft Word
格式档案的功能。 - HSLF - 提供读写
Microsoft PowerPoint
格式档案的功能。 - HDGF - 提供读写
Microsoft Visio
格式档案的功能。
二、POI-Excel 写
1、创建项目
创建一个空项目和一个普通Maven的Module
2、引入依赖
Excel有两种不同的版本,需要导入两种不同的依赖
- Excel
2003
版本的后缀名为.xls
- Excel
2007
版本的后缀名为.xlsx
<dependencies><!-- xls03 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><!-- xlsx07 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version></dependency><!--日期格式化工具--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10.1</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
3、步骤
Java万物都是对象,所以用Java操作Excel,就是操作其中一个一个的对象
Excel表中的对象
- 工作簿
- 工作表
- 行
- 单元格
我们首先编写03版本的代码:
注:
03 | 07 版本的写操作,就是对象不一样,方法都是一样的。
2003 版本和 2007 版本存在兼容性问题, 03 版本最多只有 65535 行。
1. 创建工作簿
首先要创建一个工作簿Workbook
,他有三个实现类
HSSFWorkbook
:操作03版本的ExcelSXSSFWorkbook
:XSSFWorkbook
的升级版,加速处理XSSFWorkbook
:操作07版本的Excel
操作07版本的Excel时,我们一般使用SXSSFWorkbook
//创建一个03版本的工作簿
Workbook workbook = new HSSFWorkbook();
2. 创建工作表
再通过工作簿创建工作表
//创建一个工作表
Sheet sheet=workbook.createSheet("POI写操作");
3. 创建行
再通过工作表创建行
//创建行
Row row1 = sheet.createRow(0);//第一行
Row row2 = sheet.createRow(1);//第二行
4. 创建单元格
最后通过行创建单元格
//创建单元格
Cell cell11 = row1.createCell(0);//(1,1)
Cell cell12 = row1.createCell(1);//(1,2)
5. 单元格中填入数据
//向单元格中写入数据
cell11.setCellValue("POI");
cell12.setCellValue("first");
6. 通过IO流生成表
//生成一张表(IO流)
String path = "D:\\学习\\IDEA project\\POI";
FileOutputStream fileOutputStream = new FileOutputStream(path + "03.xls");
workbook.write(fileOutputStream);
//关闭流
fileOutputStream.close();
03版本完整代码
将上述代码汇总
@Test
public void testWrite03() throws Exception {//创建一个03版本的工作簿Workbook workbook = new HSSFWorkbook();//创建一个工作表Sheet sheet = workbook.createSheet("POI写操作");//创建行Row row1 = sheet.createRow(0);//第一行Row row2 = sheet.createRow(1);//第二行//创建单元格Cell cell11 = row1.createCell(0);//(1,1)Cell cell12 = row1.createCell(1);//(1,2)//向单元格中写入数据cell11.setCellValue("POI");cell12.setCellValue("first");//生成一张表(IO流)String path = "D:\\学习\\IDEA project\\POI";FileOutputStream fileOutputStream = new FileOutputStream(path + "03.xls");workbook.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("03表生成完毕");
}
然后点击运行,可以看到左边新生成的.xls
文件
我们打开查看结果,正确
07版本完整代码
同样,以此类推,我们写出07版本的代码
@Test
public void testWrite07() throws Exception {//创建一个07版本的工作簿Workbook workbook = new SXSSFWorkbook();//创建一个工作表Sheet sheet = workbook.createSheet("POI写操作2");//创建行Row row = sheet.createRow(0);//创建单元格Cell cell11 = row.createCell(0);Cell cell12 = row.createCell(1);//向单元格中写入数据cell11.setCellValue("POI");cell12.setCellValue("second");//生成一张表(IO流)String path = "D:/学习/IDEA project/POI/";FileOutputStream fileOutputStream = new FileOutputStream(path + "07.xlsx");workbook.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("07表生成完毕");
}
大文件写 HSSF(03)
**缺点:**最多只能处理 65536 行,否则会抛出异常
**优点:**过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快。
@Test
public void HSSFWriteBigData() throws Exception {//起始时间long begin = System.currentTimeMillis();//创建工作簿Workbook workbook = new HSSFWorkbook();//创建工作表Sheet sheet = workbook.createSheet("大数据写HSSF");//写入数据for (int rowNum = 0; rowNum < 65536; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}//生成表String path = "D:/学习/IDEA project/POI/";FileOutputStream fileOutputStream = new FileOutputStream(path + "BigData03.xls");workbook.write(fileOutputStream);fileOutputStream.close();//结束时间long end = System.currentTimeMillis();System.out.println(end - begin + "ms");System.out.println("BigData03表生成完毕");
}
点击运行,整个过程运行时间为1.93s,速度很快
查看我们生成的表
如果我们超过了65536,则报错,提示范围为0~65535
大文件写 XSSF(07)
**缺点:**写数据时速度非常慢,非常耗内存,也会发生内存溢出,如 100 万条数据。
**优点:**可以写较大的数据量,如 20 万条。
@Test
public void XSSFWriteBigData() throws Exception {//起始时间long begin = System.currentTimeMillis();//创建工作簿Workbook workbook = new XSSFWorkbook();//创建工作表Sheet sheet = workbook.createSheet("大数据写XSSF");//写入数据for (int rowNum = 0; rowNum < 65537; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}//生成表String path = "D:/学习/IDEA project/POI/";FileOutputStream fileOutputStream = new FileOutputStream(path + "BigData07.xlsx");workbook.write(fileOutputStream);fileOutputStream.close();//结束时间long end = System.currentTimeMillis();System.out.println(end - begin + "ms");System.out.println("BigData07表生成完毕");
}
点击运行,整个过程报名时间为7s,耗时很慢
大文件写 SXSSF(07)
优点:
- 可以写非常大的数据量,如 100 万条甚至更多,写数据速度快,占用更少的内存。
注意:
- 过程总会产生
临时文件
,需要清理临时文件。 - 默认由 100 条记录被保存在内存中,则最前面的数据被写入临时文件。
- 如果想要自定义内存中数据的数量,可以使用 new SXSSFWorkbook (数量)。
SXSSFWorkbook 来自官方的解释:实现“BigGridDemo” 策略的流式 SXSSFWorkbook 版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。
请注意,仍然可能会消耗大量内存,这些内存基于你正在使用的功能,例如合并区域,注释。。。仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。
@Test
public void SXSSFWriteBigData() throws Exception {//起始时间long begin = System.currentTimeMillis();//创建工作簿Workbook workbook = new SXSSFWorkbook();//创建工作表Sheet sheet = workbook.createSheet("大数据写XSSF");//写入数据for (int rowNum = 0; rowNum < 65537; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}//生成表String path = "D:/学习/IDEA project/POI/";FileOutputStream fileOutputStream = new FileOutputStream(path + "BigDataS07.xlsx");workbook.write(fileOutputStream);fileOutputStream.close();//清除临时文件((SXSSFWorkbook) workbook).dispose();//结束时间long end = System.currentTimeMillis();System.out.println(end - begin + "ms");System.out.println("BigDataS07表生成完毕");
}
点击运行,整个过程运行时间为2.10s,速度相比XSSF
有了很大的提升
三、POI-Excel 读
实验表格会员消费商品明细表.xls
:
03版本
String path = "D:/学习/IDEA project/POI/会员消费商品明细表.xls";@Test
public void testRead03() throws Exception {//获取文件流FileInputStream fileInputStream = new FileInputStream(path);//创建工作簿,传入文件流Workbook workbook = new HSSFWorkbook(fileInputStream);//得到工作表Sheet sheet = workbook.getSheetAt(0);//得到行Row row = sheet.getRow(0);//得到列Cell cell = row.getCell(0);//注意获取值的类型,不同类型,需要调用不同的方法System.out.println(cell.getStringCellValue());//关闭流fileInputStream.close();
}
运行结果:
07版本
实验表格会员消费商品明细表.xlsx
:
String path = "D:/学习/IDEA project/POI/会员消费商品明细表.xlsx";@Test
public void testRead03() throws Exception {//获取文件流FileInputStream fileInputStream = new FileInputStream(path);//创建工作簿,传入文件流Workbook workbook = new XSSFWorkbook(fileInputStream);//得到工作表Sheet sheet = workbook.getSheetAt(0);//得到行Row row = sheet.getRow(0);//得到列Cell cell = row.getCell(0);//注意获取值的类型,不同类型,需要调用不同的方法System.out.println(cell.getStringCellValue());//关闭流fileInputStream.close();
}
运行结果:
不同的数据类型的读取
实验表格会员消费商品明细表.xls
:
String path = "D:/学习/IDEA project/POI/会员消费商品明细表.xls";@Test
public void ReadDifferentType() throws Exception {//获取文件流FileInputStream fileInputStream = new FileInputStream(path);//创建工作簿,传入文件流Workbook workbook = new HSSFWorkbook(fileInputStream);//得到工作表Sheet sheet = workbook.getSheetAt(0);//得到行//遍历标题行(第一行)每个单元格,输出其内容Row row = sheet.getRow(0);if (row != null) {int cellCount = row.getPhysicalNumberOfCells();//获取单元格数量for (int cellNum = 0; cellNum < cellCount; cellNum++) {//遍历单元格Cell cell = row.getCell(cellNum);if (cell != null) {int cellType = cell.getCellType();//获得单元格内容数据类型String cellValue = cell.getStringCellValue();System.out.print(" | " + cellValue);}}}//获取表中的内容int numberOfRows = sheet.getPhysicalNumberOfRows();//获得总行数for (int i = 1; i < numberOfRows; i++) {//从第二行开始遍历所有的行Row row2 = sheet.getRow(i);if (row2 != null) {int numberOfCells = row2.getPhysicalNumberOfCells();//获取每行单元格数量for (int j = 0; j < numberOfCells; j++) {Cell cell = row2.getCell(j);if (cell != null) {int cellType = cell.getCellType();String cellValue = "";//单元格内容switch (cellType) {//字符串case Cell.CELL_TYPE_STRING:System.out.print("【STRING】");cellValue = cell.getStringCellValue();break;//布尔case Cell.CELL_TYPE_BOOLEAN:System.out.print("【BOOLEAN】");cellValue = String.valueOf(cell.getBooleanCellValue());break;//空case Cell.CELL_TYPE_BLANK:System.out.print("【BLANK】");break;//数字case Cell.CELL_TYPE_NUMERIC:System.out.print("【NUMERIC】");if (DateUtil.isCellDateFormatted(cell)) {//日期System.out.print("【日期】");Date date = cell.getDateCellValue();cellValue = new DateTime(date).toString();} else {// 不是日期格式,防止数字过长System.out.print("【装换为字符串输出】");cell.setCellType(Cell.CELL_TYPE_STRING);cellValue = cell.toString();}break;case HSSFCell.CELL_TYPE_ERROR:System.out.print("【数据类型错误】");break;}System.out.println(cellValue);}}}}//关闭流fileInputStream.close();
}
运行结果:
含计算公式的单元格读取
实验表格计算公式.xls
:
@Testpublic void Formula() throws Exception {String path = "D:/学习/IDEA project/POI/计算公式.xls";//获取文件流FileInputStream fileInputStream = new FileInputStream(path);//创建工作簿,传入文件流Workbook workbook = new HSSFWorkbook(fileInputStream);//得到工作表Sheet sheet = workbook.getSheetAt(0);//得到行(有公式的那一行)Row row = sheet.getRow(4);//得到计算公式FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook);//获取单元格Cell cell = row.getCell(0);//通过公式计算输出单元格的内容int cellType = cell.getCellType();if (cellType == Cell.CELL_TYPE_FORMULA) {String cellFormula = cell.getCellFormula();System.out.println(cellFormula);//计算并打印计算结果CellValue value = formulaEvaluator.evaluate(cell);String cellValue = value.formatAsString();System.out.println(cellValue);}//关闭流fileInputStream.close();}
运行测试,结果与表格相同:
Apache POI:解决数据库和Excel之间相互转换的烦恼~相关推荐
- sql2java-excel(二):基于apache poi实现数据库表的导出的spring web支持
sql2java是我几年年开始写的一个sql2java是一个轻量级数据库(SQL)访问代码(java)生成器.这几年一直在根据工作需要维护升级,最近的项目中需要对数据库的记录提供导出excel的功能. ...
- sql2java-excel(一):基于apache poi实现数据库表的导出及支持spring web
sql2java是我几年年开始写的一个sql2java是一个轻量级数据库(SQL)访问代码(java)生成器.这几年一直在根据工作需要维护升级,最近的项目中需要对数据库的记录提供导出excel的功能. ...
- 仅用Python三行代码,实现数据库和excel之间的导入导出
目录 一.前言 二.python代码 2.1 从MySQL数据库导入csv 2.2 从csv导入MySQL数据库 三.讲解视频 一.前言 之前我分享过两次python的高效编程技巧,分别是, pyth ...
- 【Apache POI】Java写入Excel文件
上篇文章学习了Java读取Excel文件,这篇文章接着来简单总结Java写入Excel,话不多说,看代码: import java.io.File; import java.io.FileInputS ...
- 【Apache POI】Java 读取Excel文件
Excel内容如下: 封装Excel行列字段的Bean: public class Employee {private String name;private String gender;privat ...
- SpringMVC + Apache POI 实现WEB中Excel下载功能
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- 利用Apache POI读取并解析Excel的数据
/* * Created on 2010-12-9 * java读取excel文件 * */ import java.io.FileInputStream; import java.io.Fi ...
- 三行Python代码,实现数据库和excel之间的导入导出!
大家好,我是辰哥 之前有小伙伴私信我使用python如何将excel文件与mysql之间进行快速转换?今天我把这个方案写出来供大家参考. 数据库->Excel 使用Python代码实现数据从数据 ...
- 关于org.apache.poi.ss.usermodel 操作excel数据丢失问题
今日测试发现excel 有一列为空 会导致后面的列数据丢失 特此记录一下修改的bug //获得当前sheet工作表Sheet sheet = workbook.getSheetAt(sheetNum) ...
最新文章
- ios hitTest及扩展---分解ZFPlayer
- 九十五、轻松搞定Python中的Excel办公自动化系列
- 视频时代的大数据:问题、挑战与解决方案
- ❤️万字总结八大排序:冒泡排序,选择排序,插入排序,堆排序,希尔排序,归并排序,计数排序❤️
- 可交互绘图——鼠标移到点的上方会显示该点的标签[jupyter notebook]
- RAP框架练习(续)
- 卷积神经网络问题总结
- iOS第三方开源库的吐槽和备忘
- 【工作日志】2013-02-01
- MLOps- 吴恩达Andrew Ng Selecting and Training a Model Week2 论文等资料汇总
- (转)Extjs4 展示图片与图片的更新
- VS2010SP1中文版安装问题
- jdk8下载与安装教程
- 360路由器v2刷第三方固件_斐讯K2P MTK版简单几步刷入breed教程,附刷第三方固件方法...
- flink不等于符号问题
- 小米手机 VS 阿里手机,阿里输在512MB内存,华为Honor只有电池容量跟小米差不多...
- java 自动填充,使用java自动填充,实现mysql的创建修改时间的自动填充
- 蓝桥杯十大常见天阶功法——炎之呼吸.叁之型.动态规划--(上篇)
- UART2USB芯片PL2303驱动安装说明
- 乔巴机器人 番外篇_乔巴机器人五只合体图+10个小乔巴+【附合体动图】
热门文章
- 2021-2027年中国室内定位市场研究及前瞻分析报告
- 2022-2028年中国IT外包市场投资分析及前景预测报告
- mysql5.6.46安装教程_鲲鹏云-arm平台 mysql-5.6.46 安装
- 2022-2028年中国ITO薄膜行业市场全景调查及投资前景趋势报告
- Python 标准库之 Queue
- SpringCloud Alibaba 微服务架构版本说明
- LeetCode简单题之二叉树中第二小的节点
- 华为4D成像雷达、智能驾驶平台MDC 810
- 内存缓存LruCache的简单使用
- 2021年腾讯云安装Docker最简洁方法