手把手教你用java读写excel表格文件(POI,EasyExcel)

视频链接-我是学习之星我为狂神打call~
【狂神说Java】POI及EasyExcel一小时搞定通俗易懂


想给项目添加一个表格导入导出功能吗?
“xxx管理系统”没有导入导出功能逼格不够了?
想简单入手下 how to 用java 生成excel又找不到合适的教程?

come on !这篇文章简单介绍下如何用java操作excel,主要涉及到POIeasyExcel这两个

文章目录

  • 1.POI和easyExcel介绍
    • 是什么?
    • 有什么用?
  • 2.POI-excel-写
    • excel 基本写入操作
      • 03版本xls
      • 07版本xlsx
    • 大量数据写入
      • 大文件写HSSF
      • 大文件写XSSF
      • 大文件写SXSSF
  • 3.POI-excel-读
    • 03/07版本
      • 03版本代码示例
      • 07版本代码示例
    • 读取不同类型的数据(难点★)
    • 计算公式(了解即可)
  • 4.EasyExcel相关的操作
    • 导入依赖
    • 写入测试
      • 1.DemoData.java
      • 2.测试写入数据
    • 最终的结果

1.POI和easyExcel介绍

是什么?

我们经常需要将项目中的表格数据或者文档数据进行导入或者导出操作,这个如果自己从零开始做还比较麻烦。比如我之前就职的公司都是自己做的组件,但是很不好用,BUG 太多。关于表格导入导出,市面上比较知名的开源就是 Apache 的POI 和 阿里巴巴的 EasyExcel了。EasyExcel 也是对 POI 的改进和封装, 更加好用。

有什么用?

1、将用户的信息导出为 excel 表格。

2、将 Excel 表中的信息录入到网站数据库。

开发中经常会涉及到 excel 的 处理,如导出 Excel ,导入 Excel 到数据库中。

操作 Excel 目前比较流行的就是 Apache POI 和阿里巴巴的 EasyExcel。

Apache POI
结构:
在这里插入图片描述

EasyExcel
EasyExcel 是阿里巴巴开源的一个 excel处理框架,以使用简单、节省内存著称。

EasyExcel 能大大减少内存占用的主要原因是在解析 Excel 时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

下面是 EasyExcel 和 POI 在解析Excel 时的对比图。
在这里插入图片描述

2.POI-excel-写

excel 基本写入操作

在这里插入图片描述
万物皆对象:工作簿是个对象,其中包含工作表;工作表是个对象,其中包含行,列对象。。
在这里插入图片描述

03版本xls

	@Testpublic void testWriteTest03() throws Exception {// 1.创建一个工作簿Workbook workbook =new HSSFWorkbook();// 2.创建一个工作表Sheet sheet = workbook.createSheet("学生统计表");// 3.创建一个行(1,1)Row row1 =sheet.createRow(0);// 4.创建一个单元格 (1,2)Cell cell11 =row1.createCell(0);cell11.setCellValue("学生姓名");Cell cell12 =row1.createCell(1);cell12.setCellValue("杨涛");//第二行Row row2 =sheet.createRow(1);Cell cell21 =row2.createCell(0);cell21.setCellValue("入学时间");//( 2,2)Cell cell22 =row2.createCell(1);String time = new DateTime().toString("yyyy-MM-dd");cell22.setCellValue(time);// 生成一张表(IO流) 03 版本使用的就是 xls结尾!FileOutputStream fileOutputStream = new FileOutputStream(PATH + "学生统计表03.xls");workbook.write(fileOutputStream);// 关闭流fileOutputStream.close();System.out.println("学生统计表03表格生成完毕");}

07版本xlsx

	@Testpublic void testWriteTest07() throws Exception {// 1.创建一个工作簿 07Workbook workbook =new XSSFWorkbook();// 2.创建一个工作表Sheet sheet = workbook.createSheet("学生统计表");// 3.创建一个行(1,1)Row row1 =sheet.createRow(0);// 4.创建一个单元格 (1,2)Cell cell11 =row1.createCell(0);cell11.setCellValue("学生姓名");Cell cell12 =row1.createCell(1);cell12.setCellValue("杨涛");//第二行Row row2 =sheet.createRow(1);Cell cell21 =row2.createCell(0);cell21.setCellValue("入学时间");//( 2,2)Cell cell22 =row2.createCell(1);String time = new DateTime().toString("yyyy-MM-dd");cell22.setCellValue(time);// 生成一张表(IO流) 03 版本使用的就是 xlsx结尾!FileOutputStream fileOutputStream = new FileOutputStream(PATH + "学生统计表07.xlsx");workbook.write(fileOutputStream);// 关闭流fileOutputStream.close();System.out.println("学生统计表07表格生成完毕");}

大量数据写入

PS:xls文件有行数限制(65536行)。
03版本xls对应的是HSSF格式,07版本xlsx对应的是XSSF格式
注意:03版本xls写的行数超过65536会报错异常:

java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)

xlsx

大文件写HSSF

@Testpublic void testWrite03BigData() throws Exception {// 时间long begin = System.currentTimeMillis();// 创建一个簿Workbook workbook = new HSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 65535; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");// 输出文件FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite03BigData.xls");workbook.write(outputStream);// 关闭流outputStream.close();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}

大文件写XSSF

// 耗时较久!!@Testpublic void testWrite07BigData() throws Exception {// 时间long begin = System.currentTimeMillis();// 创建一个簿Workbook workbook = new XSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 200000; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");// 输出文件FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite07BigData.xlsx");workbook.write(outputStream);// 关闭流outputStream.close();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}

大文件写SXSSF

在这里插入图片描述

	@Testpublic void testWrite07BigDataSecond() throws Exception {// 时间long begin = System.currentTimeMillis();// 创建一个簿Workbook workbook = new SXSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 200000; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");// 输出文件FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite07BigDataSecond.xlsx");workbook.write(outputStream);// 关闭流outputStream.close();// 清除临时文件!((SXSSFWorkbook)workbook).dispose();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}

3.POI-excel-读

03/07版本

03版本代码示例

    String PATH = "C:\\Users\\Administrator\\Desktop\\poi-easyExcel\\";@Testpublic void testReadTest03() throws Exception {// 获取文件流FileInputStream inputStream = new FileInputStream(PATH + "poi学生统计表03.xls");// 1.创建一个工作簿, excel 能操作的它都能操作Workbook workbook = new HSSFWorkbook(inputStream);// 2.得到表Sheet sheet = workbook.getSheetAt(0);// 3.得到行Row row = sheet.getRow(0);// 4.得到列Cell cell = row.getCell(1);// 输出(0,0)// 读取值的时候一定要注意判断类型,否则会读取失败System.out.println(cell.getStringCellValue());}

07版本代码示例

    @Testpublic void testReadTest07() throws Exception {// 获取文件流FileInputStream inputStream = new FileInputStream(PATH + "poi学生统计表07.xlsx");// 1.创建一个工作簿, excel 能操作的它都能操作Workbook workbook = new XSSFWorkbook(inputStream);// 2.得到表Sheet sheet = workbook.getSheetAt(0);// 3.得到行Row row = sheet.getRow(0);// 4.得到列Cell cell = row.getCell(1);// 输出(0,0)// 读取值的时候一定要注意判断类型,否则会读取失败System.out.println(cell.getStringCellValue());}

注意获取值的类型即可

读取不同类型的数据(难点★)

    @Testpublic void testCellType() throws Exception {// 获取文件流FileInputStream inputStream = new FileInputStream(PATH + "明细表.xls");// 1.创建一个工作簿, excel 能操作的它都能操作Workbook workbook = new HSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);// 获取标题内容Row rowTitle = sheet.getRow(0);if (rowTitle != null) {// 一定要掌握!!int cellCount = rowTitle.getPhysicalNumberOfCells();for (int cellNum = 0; cellNum < cellCount; cellNum++) {Cell cell = rowTitle.getCell(cellNum);if (cell != null) {int cellType = cell.getCellType();String cellValue = cell.getStringCellValue();System.out.print(cellValue + " | ");}}System.out.println();}// 获取表中的内容int rowCount = sheet.getPhysicalNumberOfRows();for (int rowNum = 1; rowNum < rowCount; rowNum++) {Row rowData = sheet.getRow(rowNum);if (rowData != null) {// 读取列int cellCount = rowTitle.getPhysicalNumberOfCells();for (int cellNum = 0; cellNum < cellCount; cellNum++) {System.out.print("[" + (rowNum + 1) + "-" + (cellNum + 1)+"]");Cell cell = rowData.getCell(cellNum);// 匹配数据的类型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_NUMERIC:    //数字System.out.print("[numeric]");if (HSSFDateUtil.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;default:System.out.print("[数据类型错误!]");break;}System.out.println(cellValue);}}}}// 关闭流inputStream.close();}

注意类型转换!!

计算公式(了解即可)

 @Testpublic void testWrite07BigDataSecond() throws Exception {// 时间long begin = System.currentTimeMillis();// 创建一个簿Workbook workbook = new SXSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 200000; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");// 输出文件FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite07BigDataSecond.xlsx");workbook.write(outputStream);// 关闭流outputStream.close();// 清除临时文件!((SXSSFWorkbook)workbook).dispose();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}

4.EasyExcel相关的操作

EasyExcel官方示例

导入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.1.2-beat1</version>
</dependency>

写入测试

在这里插入图片描述
对象

@Data
public class DemoData {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ExcelProperty("数字标题")private Double doubleData;/*** 忽略这个字段*/@ExcelIgnoreprivate String ignore;
}

1.DemoData.java

/*** 最简单的写* <p>1. 创建excel对应的实体对象 参照{@link DemoData}* <p>2. 直接写即可*/
@Test
public void simpleWrite() {// 写法1String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 上面那个fileName不一定非得按人家的格式写,只要能保证该文件能确定一个文件就可以了// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可/*他这个默认是xlsx格式的,第一个参数是文件名(绝对路径),第二个参数是哪个模板,比如上面定义的DemoData对象sheet("模板") 是说生成的工作簿(fileName)中含有一个叫“模板”的表doWrite中的参数 data()返回的就是需要写入的数据!*/EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}

PS:我这里的data()是这样写的

private List<DemoData> data() {List<DemoData> list = new ArrayList<DemoData>();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}

2.测试写入数据

@Test测试下吧

最终的结果

如案例图所示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/482711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

欢迎参加2022年第一次《城市大脑建设标准规范》专家研讨会

来源&#xff1a;世界数字大脑标准研究组2018年以来&#xff0c;城市大脑正成为智慧城市和智能产业的新热点&#xff0c;有近500个城市提出城市大脑的建设规划&#xff0c;数千家大中型科技企业进入城市大脑的建设领域。如何理清城市大脑的概念和定义&#xff0c;制定统一的城市…

Spring常用注解的讲解

转载&#xff0c;原文链接 作者&#xff1a;字母哥博客 本文出自&#xff1a;springboot深入浅出系列 文章目录一、常用注解回顾1.1 RequestBody与ResponseBody1.2. RequestMapping注解1.3. RestController与Controller1.4. PathVariable 与RequestParam二、接收复杂嵌套对象参…

复杂系统与人工生命:十年研究概览

来源&#xff1a;集智俱乐部作者&#xff1a;Thomas McAtee、Claudia Szabo译者&#xff1a;陈翔 审校&#xff1a;刘培源编辑&#xff1a;邓一雪导语人工生命&#xff08;artificial life&#xff09;是通过仿真建模、机器技术和生物化学等方式模拟自然生命系统&#xff0c;进…

5.1传输层概述

5.1传输层概述 文章目录传输层概述传输层的两个协议传输层的寻址与端口传输层概述 传输层的两个协议 传输层的寻址与端口

多细胞生命进击之路:单细胞为何放弃自由,长成复杂的多细胞?

来源&#xff1a;集智俱乐部作者&#xff1a;Veronique Greenwood译者&#xff1a;赵雨亭审校&#xff1a;张澳编辑&#xff1a;邓一雪导语人类作为复杂的多细胞生命&#xff0c;似乎理所当然地认为&#xff0c;多细胞生命相对单细胞生命有绝对的优势。但实际上单细胞生命进化为…

5.2 UDP协议

5.2 UDP协议 文章目录用户数据报协议udp概述udp首部形式udp校验用户数据报协议udp概述 udp首部形式 udp校验

焦李成院士:进化优化与深度学习的思考

来源&#xff1a;AI科技评论作者&#xff1a;焦李成整理&#xff1a;维克多编辑&#xff1a;青暮2021年12月17日&#xff0c;西安电子科技大学人工智能学院教授、欧洲科学院外籍院士、IEEE Fellow焦李成受邀参加2021中国计算机大会“下一代演化计算发展趋势”论坛&#xff0c;并…

5.3.1 TCP协议特点和TCP报文段格式

5.3.1 TCP协议特点和TCP报文段格式 文章目录tcp协议的特点tcp 报文段首部格式tcp协议的特点 tcp 报文段首部格式

互补性:从不同的角度思考同一个事物时,发现它同时具有不同甚至相互矛盾的性质...

来源&#xff1a;混沌巡洋舰检验一流智力的标准是头脑中能同时持有两种截然相反的观点&#xff0c;却能并行不悖。——弗朗西斯斯科特菲茨杰拉德显然&#xff0c;这种互补性推翻了学术的本体论。真理是什么&#xff1f;我们之所以要提出彼拉多的问题&#xff0c;并不是出于怀疑…

5.3.2 TCP连接管理

5.3.2 TCP连接管理 文章目录tcp 连接管理tcp的连接简历TCP传输连接中的SYN、ACK、SEQ、 AN分别是什么意思?syn洪泛攻击tcp的连接释放tcp 连接管理 tcp的连接简历 TCP传输连接中的SYN、ACK、SEQ、 AN分别是什么意思? syn洪泛攻击 tcp的连接释放

2021年量子计算的研发现状与未来展望

来源&#xff1a;AI科技评论作者&#xff1a;杏花编辑&#xff1a;青暮从硬件、软件和算法以及各国政策等方面展现量子技术最新进展。超导量子计算过去宣称实现的量子霸权在最新的获得戈登贝尔奖被宣告打破&#xff0c;但谷歌和IBM依然在这一领域有着雄心勃勃的计划。离子阱则凭…

5.3.3 TCP可靠传输

5.3.3 TCP可靠传输 文章目录

【动态规划】洛谷 P1282 多米诺骨牌

【动态规划】洛谷 P1282 多米诺骨牌 时间限制: 1 Sec 内存限制: 128 MB 题目描述 多米诺骨牌有上下2个方块组成&#xff0c;每个方块中有1~6个点。现有排成行的 上方块中点数之和记为S1&#xff0c;下方块中点数之和记为S2&#xff0c;它们的差为|S1-S2|。例如在图8-1中&#…

深度学习在工业推荐如何work?Netflix这篇论文「深度学习推荐系统Netflix案例分析」阐述DL在RS的优劣与经验教训...

来源&#xff1a;专知深度学习在推荐系统中如何发挥作用是一个重要的问题。最近来自Netflix的文章详细阐述了这一点指出&#xff1a;在建模用户物品交互方面&#xff0c;深度学习相比传统基线方法并无太大优势&#xff0c;而对于异质特征的表示融入深度学习则具有很好建模性能。…

5.3.4 TCP流量控制

5.3.4 TCP流量控制 文章目录tcp流量控制tcp流量控制

Nature封面,硅量子计算达到99%的准确率

来源&#xff1a;ScienceAI编辑&#xff1a;萝卜皮在 2022 年 1 月 20 日发布的《Nature》上&#xff0c;有三篇论文独立介绍了基于硅的量子计算平台&#xff0c;它们使用了多量子比特纠缠&#xff1a;一篇来自新南威尔士大学&#xff08;UNSW&#xff09; Andrea Morello 团队…

[poj3261]Milk Patterns

求出后缀数组和height数组&#xff0c;然后二分答案后分组查询&#xff0c;一个块内如果有超过k个那么这个答案就可以。 1 #include<bits/stdc.h>2 using namespace std;3 #define N 500054 int n,m,ans,a[N],b[N],h[N],sum[N],ra[N<<1],sa[N];5 char s[N],s1[N];6…

5.3.5 TCP拥塞控制

5.3.5 TCP拥塞控制 文章目录流量控制与拥塞控制区别

一文读懂2022年国家自然科学基金限项新旧政策对比

来源&#xff1a;国家自然科学基金委员会、微信公众号“锐动源”近日&#xff0c;《2022年度国家自然科学基金项目指南》正式发布&#xff0c;相较于2021年的项目指南&#xff0c;从对比来看&#xff0c;2022年度项目指南变动不大&#xff0c;最重要的几项改革在指南发布前均已…