在应用程序开发的过程中,经常需要使用Excel文件来进行数据的导入导出,所以在java语言实现此类需求时,往往会面临着Excel文件的解析(导入)或(导出)。

在java技术圈里,可以进行Excel文件处理的主流技术包括:Apache POI, JXL,Alibaba EasyExcel等

我们今天主要说说Apache POI技术 和 Alibaba EasyExcel:

Apache POI基于DOM方式解析,将文件直接加载内存,所以速度较快,适合Excel文件数据不大的场景。

Alibaba EasyExcel 采用逐行读取的解析方式,将每一行解析结果以观察者的模式通知处理,所以适合数据量较大的Excel文件解析。

Apache POI是用Java编写的免费开源的跨平台的Java API, Apache POI提供Java程序对Microsoft office格式档案进行读写功能的API开源库。

而我们经常使用开源库内的XSSF解析Excel文件,它里面提供了读写Excel格式文件的功能。

这里就需要提到Workbook接口(代表一个Excel文件),用于创建或解析Excel文件,常见实现类XSSFworkbook;

当我们要解析一个Excel文件时,需要知道它的内部结构,有若干个sheet(工作簿),sheet里有若干行,行里有若干单元格。

读取Excel:

public static void main(String[] args) {try (Workbook workbook = new XSSFWorkbook(new FileInputStream("C:\\Users\\Administrator\\Documents\\Tencent Files\\2837047212\\FileRecv\\1627356552686.xlsx"))) {//获取工作簿Sheet sheet = workbook.getSheetAt(0);//方式1//遍历工作簿中所有行for (Row row : sheet) {//按照下标获取当前行的单元格Cell cell0 = row.getCell(0);//序号Cell cell1 = row.getCell(1);//部门Cell cell2 = row.getCell(2);//姓名Cell cell3 = row.getCell(3);//职位Cell cell4 = row.getCell(4);//身份证号System.out.println("序号:" + (int)cell0.getNumericCellValue());System.out.println("部门:" + cell1.getStringCellValue());System.out.println("姓名:" + cell2.getStringCellValue());System.out.println("职位:" + cell3.getStringCellValue());System.out.println("身份证号:" + cell4.getStringCellValue());System.out.println();}//方法2
//          for (int i = 0; i <= sheet.getLastRowNum(); i++) {
//              Row row = sheet.getRow(i);
//              //按照下标获取当前行的单元格
//              Cell cell0 = row.getCell(0);//序号
//              Cell cell1 = row.getCell(1);//部门
//              Cell cell2 = row.getCell(2);//姓名
//              Cell cell3 = row.getCell(3);//职位
//              Cell cell4 = row.getCell(4);//身份证号
//
//              System.out.println("序号:" + (int)cell0.getNumericCellValue());
//              System.out.println("部门:" + cell1.getStringCellValue());
//              System.out.println("姓名:" + cell2.getStringCellValue());
//              System.out.println("职位:" + cell3.getStringCellValue());
//              System.out.println("身份证号:" + cell4.getStringCellValue());
//              System.out.println();
//          }} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

在解析时候,需要传入需要解析的Excel文件的路径(因为它是以流的方式传入,所以会出现异常),然后获取Excel文件里的工作簿,再从工作簿中获取行,再从行获取单元格,层层递进,都通过get方法来获取对应的值;

当我们要去遍历工作簿中所有行或所有单元格时,用foreash或for循环都可以遍历;

创建Excel:

     public static void main(String[] args) {try (Workbook workbook = new XSSFWorkbook();FileOutputStream out = new FileOutputStream("D:\\20220529\\20220708\\Demo.xlsx")) {//创建工作簿SheetSheet sheet0 = workbook.createSheet("2020数据列表");Sheet sheet1 = workbook.createSheet("2021数据列表");Sheet sheet2 = workbook.createSheet("2022数据列表");//创建数据行RowRow row0 = sheet0.createRow(0);//创建单元格Cell cell0 = row0.createCell(0);cell0.setCellValue(UUID.randomUUID().toString());Cell cell1 = row0.createCell(1);cell1.setCellValue(Math.random() * 1000);Cell cell2 = row0.createCell(2);cell2.setCellValue(LocalDateTime.now());workbook.write(out);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

创建工作簿和解析时候类似,首先通过createSheet创建工作簿,再在工作簿中通过createRow创建行,再在行里通过createCell创建单元格,通过set方法将内容写入行和单元格,最后通过workbook里的write方法将所写的内容通过输出流写入所输出的路径。

在一个Excel工作表中创建工作簿,需要先通过输入流将Excel路径读取到控制台,再通过输出流将在控制台上创建好的工作簿写入到这个Excel中,实现代码如下:

 List<String> list = Arrays.asList("妲己","貂蝉","立新","夏侯惇","曹操","马克","百里","鲁班","王昭君");//读取一个已经存在的Excel文件try (Workbook workbook = new XSSFWorkbook(new FileInputStream("D:\\20220529\\20220708\\data.xlsx"));FileOutputStream out = new FileOutputStream("D:\\20220529\\20220708\\data.xlsx")) {//在“已经存在的Excel文件”创建新的sheetSheet sheet = workbook.createSheet();//获取格式编码值DataFormat  dataformat = workbook.createDataFormat();short dataformatCode = dataformat.getFormat("yyyy年MM月dd日 HH:mm:ss");short moneydataformat = dataformat.getFormat("¥#,###");//创建日期格式对象CellStyle datacellstyle = workbook.createCellStyle();datacellstyle.setDataFormat(dataformatCode);//设置格式编码值 164//创建货币格式对象CellStyle moneycellstyle = workbook.createCellStyle();moneycellstyle.setDataFormat(moneydataformat);//设置格式编码值//列头Row row = sheet.createRow(0);Cell cell0 = row.createCell(0);cell0.setCellValue("序号");Cell cell1 = row.createCell(1);cell1.setCellValue("姓名");Cell cell2 = row.createCell(2);cell2.setCellValue("时间");Cell cell3 = row.createCell(3);cell3.setCellValue("金额");for (int i = 0; i < list.size(); i++) {String name = list.get(i);//创建行Row row1 = sheet.createRow(i+1);//创建单元格Cell  cell10 = row1.createCell(0);//序号cell10.setCellValue(String.valueOf(i+1));Cell  cell11 = row1.createCell(1);//姓名cell11.setCellValue(name);Cell  cell12 = row1.createCell(2);//日期cell12.setCellStyle(datacellstyle);//日期格式对象cell12.setCellValue(new Date());Cell  cell13 = row1.createCell(3);//红包金额cell13.setCellStyle(moneycellstyle);//货币格式对象cell13.setCellValue((int)(Math.random() * 100000));}workbook.write(out);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}

当我们创建单元格时候,需要指定格式时候,可以调用workbook里的createDataFormat()方法,先获取格式编码值,再通过 workbook里createCellStyle()方法创建格式对象,再setDataFormatjiang 方法将编码值写入,再将格式对象,写入需要指定格式的单元格中。

超大Excel文件的读写:

使用POI写入:使用SXSSFWorkbook进行写入,通过设置SXSSFWorkbook的构造参数,可以设置每次在内存中保存的行数,当达到这个值时候,会将这些数据flush到磁盘上,这样就不会出现内存不足的情况。代码如下:

try (Workbook workbook = new SXSSFWorkbook(100);FileOutputStream fos = new FileOutputStream("c:\\test\\temp.xlsx")) {Sheet sheet1 = workbook.createSheet();for (int i = 0; i <= 1000000; i++) {Row row = sheet1.createRow(i);Cell cell0 = row.createCell(0);cell0.setCellValue(UUID.randomUUID().toString());Cell cell1 = row.createCell(1);cell1.setCellValue(new Date());}workbook.write(fos);
} catch (IOException e) {e.printStackTrace();
}

使用POI写入超大Excel时候会使cpu急速飙升,导致内存占用过高,这样不仅速率底,对cpu要求也高,所以我们在写入超大Excel文件时候,不推荐使用POI使用SXSSFWorkbook进行写入。我们更偏向于使用EasyExcel来对超大Excel文件进行读写。

使用EasyExcel读写:

public class Demo {public static void main(String[] args) {// 写入100wEasyExcel.write("c:\\test\\run\\easy.xlsx", Order.class).sheet("订单列表").doWrite(data());}// 创建100w条订单数据private static List<Order> data() {List<Order> list = new ArrayList<Order>();for (int i = 0; i < 1000000; i++) {list.add(new Order());}return list;}
}

写入时,EasyExcel类write方法将文件地址,和实体类传入,再创建工作簿,再通过doWrite()方法将创建的数据传入其中。

读取:

EasyExcel.read("c:\\test\\run\\easy.xlsx", Order.class,new AnalysisEventListener<Order>() {@Overridepublic void invoke(Order order, AnalysisContext arg1) {// 读取每条数据orderList.add(order);}@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {// 读取到列头System.out.println(headMap);}@Overridepublic void doAfterAllAnalysed(AnalysisContext arg0) {// 读取完毕System.out.println("END");}
}).sheet().doRead();

读取时,将EasyExcel类write方法将文件地址,和实体类传入,再传入AnalysisEventListener<>(){}匿名子类,重写其中的方法,在其中可以读取每条数据,也可以读取列头。

以上就是我对Excel文件解析的理解。

Excel文件的解析相关推荐

  1. 在线EXCEL文件数据转换解析工具

    在线EXCEL文件数据转换解析工具 在线EXCEL文件数据转换解析工具 本工具支持将EXCEL文件转解析成JSON,CSV,HTML以及公式格式,直接将文件拖入文件上传区即可实时转换, 数据仅在客户端 ...

  2. Web项目,网页上传excel文件并解析实战示例

    最近写了一个基于poi解析excel文件的工具类,所以想在web项目中测试一下,就做了这个简单的项目.本项目主要使用了 SpringMVC+RESTful+Maven的风格.适合有一定基础的人员. 源 ...

  3. react接收后端文件_React获取Java后台文件流并下载Excel文件流程解析

    记录使用blob对象接收java后台文件流并下载为xlsx格式的详细过程,关键部分代码如下. 首先在java后台中设置response中的参数: public void exportExcel(Htt ...

  4. python下载邮件附件_Python - 从电子邮件附件下载excel文件然后解析它

    编辑 - 更新 我创建了一个可怕的黑客,打开excel文件,然后使用相同的文件名将其保存下来,然后将excel文件打开到pandas中.这真的太可怕但我无法通过attachment.SaveFileA ...

  5. 『Java』Zip中Excel文件的解析

    前言 永远相信美好的事情即将发生 背景 自从上一次尝试使用 EasyExcel 对文件下载接口进行解析从而完成数据的爬取之后,我便放弃了最开始使用的数据接口解析爬取,转而投入到了 Excel 的怀抱( ...

  6. 使用POI读取大量数据EXCEL文件,并解析成自定义javaBean

    1.几个javaBean的定义 因为javabean比较简单 这里就不详细写了,get set和构造方法自己定义 public class Excel {private String fileName ...

  7. ant-vue实现上传excel文件并解析内容

    安装依赖 npm install xlsx --save 引入 笔者使用vue2, 引入import xlsx from 'xlsx' 写法,笔者使用xlsx.read和xlsx.utils.shee ...

  8. Java导入Excel文件日期解析成了中文问题解决

    Excel文件日期为2018-12-12,在解析出来的时候变成了 12-十二月-2018 cell.setCellType(Cell.CELL_TYPE_STRING);//根据不同类型转化成字符串 ...

  9. EasyExcel对Excel文件的解析过程

    POI与easyExcel的区别: POI是通过WorkBook来解析表格文件的,虽然内部有使用到Sax模式,能后大大的提高效率,但是要解析大文件(10w,100w行)的话很容易出现OOM(内存溢出) ...

最新文章

  1. 从算法到硬件,一文读懂2019年 AI如何演进
  2. 脑机接口主流算法解析课程视频汇总
  3. [原]ubuntu14.04 网卡逻辑修改没有文件/etc/udev/rules.d/70-persistent-net.rules
  4. VULKAN学习笔记-inter教学四篇
  5. Educational Codeforces Round 73 (Rated for Div. 2)
  6. 2018年下半年《软件评测师》下午试卷及答案
  7. java实现定时任务 schedule_详解java定时任务
  8. 性能计数器驱动_Linux CPU性能优化方法
  9. swift网络编程入门应用:天气预报
  10. 菜鸟教程python爬虫小说_Python 爬虫介绍 | 菜鸟教程
  11. 叉乘点乘混合运算公式_《3D数学基础》提炼总结(四)向量运算(后)
  12. 花998购买的拍摄技巧和7天起号培训文档,学了一周的总结。
  13. 什么是统一身份认证?
  14. ae渲染存在偏移_以后请不要问我AE和PR有什么区别了...
  15. 我在成都火车站捡了个彝族美女 第1节:车站捡来的美女
  16. FLD5302和FLD5303升压充电芯片
  17. No unique bean of type..... Unsatisfied dependency of type
  18. 高速相机在企业生产领域的应用效果
  19. HCIE华为云计算面试-桌面云
  20. ​【斯坦福出品】吴恩达CS230深度学习课小抄来了 | 附下载

热门文章

  1. ARM base instruction -- mul
  2. 最近单位让草理的一个东西 软件包及其服务标准介绍
  3. 一级计算机综合训练第五卷,2014年计算机等级考试一级MSOFFICE综合训练(5).pdf
  4. 大厂h5开源视频系列-腾讯2012世界杯赛程魔方
  5. 【UE】高级载具插件-04-坦克瞄准开火
  6. 反向传播——计算图基础知识
  7. Ubunto使用 码云 创建项目
  8. 11亿资金助力, 微软、三星、摩根大通多数巨头加持, 枝繁叶茂的它凭什么被低估?...
  9. 数控机床各种加工模式以及英文简写
  10. git关联云效使用教程