JAVA解析EXCEL(JExcelAPI,POI,EasyExcel)

前言

文章目录

    • 前言
    • JExcelAPI
      • Demo
    • POI
      • HSSFWorkBook
      • XSSFWorkBook
        • Demo
      • SXSSFWorkBook
        • Demo
      • XSSFReader
        • Demo
    • EasyExcel
      • Demo

在这里插入图片描述

demo代码:https://github.com/RwTo/excel-demo
JAVA解析Excel 一般有三种方式

JExcelAPI
POI
EasyExcel

JExcelAPI

官网:https://jexcelapi.sourceforge.net/

  1. 仅支持 2003 版本的Excel 也就是 后缀名为 xls 的文件
  2. 采用流式处理模型,逐行读取和写入 ——因此 可以处理大量数据,一般不会出现OOM

Demo

<!--JExcelAPI--><dependency><groupId>net.sourceforge.jexcelapi</groupId><artifactId>jxl</artifactId><version>2.6.12</version></dependency>

读xls 文件

public class ReadExcelDemo {public static void main(String[] args) {try {// 1. 打开 Excel 文件String filePath = ExcelConstant.EXCEL_PATH_XLS;Workbook workbook = Workbook.getWorkbook(new java.io.File(filePath));// 2. 获取第一个工作表Sheet sheet = workbook.getSheet(0);/*** -Xms64m -Xmx64m* row = 4000 col = 50* 正常读*/// 3. 遍历每一行,并读取数据for (int row = 0; row < sheet.getRows(); row++) {for (int col = 0; col < sheet.getColumns(); col++) {Cell cell = sheet.getCell(col, row);String content = cell.getContents();content += cell.getCellFormat().getBackgroundColour().getDescription();System.out.print(content+"\t");}System.out.println();}// 4. 关闭工作簿workbook.close();} catch (Exception e) {e.printStackTrace();}}
}

写xls 文件

public class WriteExcelDemo {public static void main(String[] args) {try {String filePath = ExcelConstant.EXCEL_PATH_XLS;// 1. 创建工作簿WritableWorkbook workbook = Workbook.createWorkbook(new File(filePath));// 2. 创建工作表WritableSheet sheet = workbook.createSheet("Sheet1", 0);// 3. 定义单元格颜色WritableCellFormat greenFormat = new WritableCellFormat();greenFormat.setBackground(jxl.format.Colour.GREEN);WritableCellFormat yellowFormat = new WritableCellFormat();yellowFormat.setBackground(jxl.format.Colour.YELLOW);/*** -Xms64m -Xmx64m* row = 4000 col = 50* 正常写*/// 4. 写入数据for (int row = 0; row < 4000; row++) {for (int col = 0; col < 50; col++) {if(col%2 == 0){Label label = new Label(col, row, "Cell " + (row + 1) + "-" + (col + 1),yellowFormat);sheet.addCell(label);}else{Label label = new Label(col, row, "Cell " + (row + 1) + "-" + (col + 1),greenFormat);sheet.addCell(label);}}}// 5. 保存工作簿workbook.write();workbook.close();} catch (Exception e) {e.printStackTrace();}}
}

POI

官网:https://poi.apache.org/
功能比较丰富,使用较为广泛,问题也比较多(比如OOM)
四种API 操作Excel
官网介绍:https://poi.apache.org/components/spreadsheet/how-to.html

文档对象模型
HSSFWorkBook (功能丰富,但会OOM)
XSSFWorkBook (功能丰富,但易OOM)
事件处理模型(流式处理)
SXSSFWorkBook (只支持xlsx 的写入)
XSSFReader(仅提供模板,需要使用者自己编写)

POM 文件

<!-- Apache POI --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>

HSSFWorkBook

  1. 支持 xls 文件的解析和写入
  2. 基于DOM ,将整个 Excel 文件加载到内存中,构建一个完整的 Excel 文档对象模型树,再进行解析和操作,当文件较大时,可能会出现内存溢出
    但因为 xls 文件支持的样式和单元格数量较少,一般不会出现OOM

XSSFWorkBook

  1. 支持 xlsx 文件的解析和写入
  2. 基于DOM ,将整个 Excel 文件加载到内存中,构建一个完整的 Excel 文档对象模型树,再进行解析和操作,当文件较大时,可能会出现内存溢出

Demo

写入excel(xls,xlsx)

public class WriteExcelDemo {public static void main(String[] args) {try {String filePath = ExcelConstant.EXCEL_PATH_XLS;//String filePath = ExcelConstant.EXCEL_PATH_XLSX;//Workbook workbook = new XSSFWorkbook(); //支持xlsx文件的写入Workbook workbook = new HSSFWorkbook(); //支持xls文件的写入Sheet sheet = workbook.createSheet("Sheet1");/*** -Xms64m -Xmx64m* row = 4000 col = 50* 出现OOM*/for (int row = 0; row < 4000; row++) {Row excelRow = sheet.createRow(row);for (int col = 0; col < 50; col++) {Cell cell = excelRow.createCell(col);cell.setCellValue("Cell " + (row + 1) + "-" + (col + 1));}}FileOutputStream fileOutputStream = new FileOutputStream(filePath);workbook.write(fileOutputStream);fileOutputStream.close();workbook.close();} catch (Exception e) {e.printStackTrace();}}
}

读excel(xls,xlsx)

public class ReadExcelDemo {public static void main(String[] args) {try {String filePath = ExcelConstant.EXCEL_PATH_XLSX;//String filePath = ExcelConstant.EXCEL_PATH_XLSX;FileInputStream fileInputStream = new FileInputStream(filePath);//WorkbookFactory会根据文件类型自动选择使用HSSFWorkBook 或 XSSFWorkBookWorkbook workbook = WorkbookFactory.create(fileInputStream);Sheet sheet = workbook.getSheetAt(0);/*** -Xms64m -Xmx64m* row = 4000 col = 50* 出现OOM*/for (Row row : sheet) {for (Cell cell : row) {String cellValue = getCellValueAsString(cell);System.out.print(cellValue + "\t");}System.out.println();}fileInputStream.close();workbook.close();} catch (Exception e) {e.printStackTrace();}}private static String getCellValueAsString(Cell cell) {if (cell == null) {return "";}switch (cell.getCellType()) {case STRING:return cell.getStringCellValue();case NUMERIC:return String.valueOf(cell.getNumericCellValue());case BOOLEAN:return String.valueOf(cell.getBooleanCellValue());default:return "";}}
}

SXSSFWorkBook

  1. 仅支持xlsx 的写入
  2. 基于流式处理,逐行对excel 处理,用磁盘空间换取内存,可以高效地写入数据到 Excel 文件中,同时减少内存占用。
  3. SXSSFWorkbook 采用了内存优化的设计,避免了将所有数据加载到内存的需求。它仅将有限数量的行缓冲在内存中,写入到输出流后即丢弃缓冲的数据,从而减少了内存占用。
  4. SXSSFWorkbook 支持设置在写入数据之前保留在内存中的行数。通过控制分页大小,可以灵活地控制内存使用,特别适合处理超大型的 Excel 文件。

Demo

写入xlsx

public class SXSSFWriteExcelDemo {public static void main(String[] args) {try {// Set custom temporary directoryString customTempDirPath = "temp";System.setProperty("java.io.tmpdir", customTempDirPath);String filePath = ExcelConstant.EXCEL_PATH_XLSX_BIG;SXSSFWorkbook workbook = new SXSSFWorkbook(500);//rowAccessWindowSize为内存中缓存的记录数,默认100Sheet sheet = workbook.createSheet("Sheet1");for (int row = 0; row < 100000; row++) {Row excelRow = sheet.createRow(row);for (int col = 0; col < 3; col++) {Cell cell = excelRow.createCell(col);cell.setCellValue("Cell " + (row + 1) + "-" + (col + 1));}}FileOutputStream fileOutputStream = new FileOutputStream(filePath);workbook.write(fileOutputStream);fileOutputStream.close();//使用 dispose() 方法释放(删除) SXSSFWorkbook 使用的临时资源,特别是在写入大量数据后,这一步骤很重要。workbook.dispose();/*如果不手动释放,默认等虚拟机停止也会删除临时文件poi.keep.tmp.files 通过这个配置可以控制虚拟机停止时,不删除临时文件*///程序执行结束后,手动删除临时文件目录(看是否需要)deleteTempFiles(new File(customTempDirPath));} catch (Exception e) {e.printStackTrace();}}private static void deleteTempFiles(File directory)  {if (directory.isDirectory()) {File[] files = directory.listFiles();if (files != null) {for (File file : files) {deleteTempFiles(file);}}}if (!directory.delete()) {System.err.println("Failed to delete temp file: " + directory.getAbsolutePath());} else {System.out.println("Deleted temp file: " + directory.getAbsolutePath());}}}

XSSFReader

官网案例:https://poi.apache.org/components/spreadsheet/how-to.html#xssf_sax_api

  1. 仅支持 xlsx 的解析
  2. 基于流式处理,逐行读取单元格,不会将整个excel 存到内存,适合大型excel的处理

Demo

读xlsx


public class SAXWriteExcelDemo {public static void main(String[] args) throws Exception {String filePath = ExcelConstant.EXCEL_PATH_XLSX_BIG;InputStream is = new FileInputStream(filePath);OPCPackage opcPackage = OPCPackage.open(is);try {// 读取 Excel 文件XSSFReader reader = new XSSFReader(opcPackage);// 使用事件处理器处理 Sheet 数据SAXSheetHandler sheetHandler = new SAXSheetHandler();XSSFSheetXMLHandler xmlHandler = new XSSFSheetXMLHandler(reader.getStylesTable(), reader.getSharedStringsTable(), sheetHandler, false);XMLReader sheetParser = XMLReaderFactory.createXMLReader();sheetParser.setContentHandler(xmlHandler);Iterator<InputStream> sheetsData = reader.getSheetsData();while(sheetsData.hasNext()){InputStream sheetIs = sheetsData.next();InputSource sheet = new InputSource(sheetIs);//开始解析sheet页System.out.println("=====================================开始处理sheet页==============================================");long start = System.currentTimeMillis();sheetParser.parse(sheet);System.out.println("=====================================处理sheet结束==============================================");long end = System.currentTimeMillis();List<List<SAXCell>> curSheet = sheetHandler.getCurSheet();curSheet.forEach(System.out::println);System.out.println("处理行数:"+sheetHandler.getRowCount());System.out.println("处理单元格数:"+sheetHandler.getCellCount());System.out.println("处理时间(ms):"+(end-start));sheetHandler.clear();}} catch (IOException e) {e.printStackTrace();} catch (OpenXML4JException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();}finally {// 关闭输入流和 OPCPackageis.close();opcPackage.close();}}
}class SAXSheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {//当前页private List<List<SAXCell>> curSheet;//当前行private List<SAXCell> curRow;//总单元格数private int cellCount;public SAXSheetHandler() {this.curSheet = new LinkedList<>();}/*** 一行处理开始时** @param i 行号*/@Overridepublic void startRow(int i) {//开始处理新的一行,初始化当前行curRow = new LinkedList<>();}/*** 一行处理结束时** @param i 行号*/@Overridepublic void endRow(int i) {//一行处理结束,将这一行数据存入sheetcurSheet.add(curRow);}/*** 处理单元格(不会读取空单元格)** @param cellReference  单元格名称* @param formattedValue 单元格值* @param xssfComment    批注*/@Overridepublic void cell(String cellReference, String formattedValue, XSSFComment xssfComment) {SAXCell cell = new SAXCell(cellReference, formattedValue);curRow.add(cell);cellCount++;}@Overridepublic void headerFooter(String text, boolean isHeader, String tagName) {// 头部和页脚}@Overridepublic void endSheet() {//sheet处理结束}public List<List<SAXCell>> getCurSheet() {return curSheet;}public int getCellCount() {return cellCount;}public int getRowCount() {return curSheet.size();}public void clear(){curSheet = new LinkedList<>();cellCount = 0;}
}
@Data
class SAXCell {private String cellName;private String value;public SAXCell(String cellName, String value) {this.cellName = cellName;this.value = value;}
}

EasyExcel

官网:https://easyexcel.opensource.alibaba.com/

  1. 支持xlsx和xls 文件的解析和写入
  2. 流式处理,节省内存,可以处理大型excel
  3. 支持注解,简单易用

Demo

POM

<!--easyExcel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.0-beta2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>

实例

@Data
public class UserData {private String name;private int age;private String email;public UserData() {}public UserData(String name, int age, String email) {this.name = name;this.age = age;this.email = email;}
}

写入excel(xls,xlsx)

public class EasyWriteExcelDemo {public static void main(String[] args) {String filePath = ExcelConstant.EE_EXCEL_PATH_XLSX_BIG;// 创建写入的数据列表List<UserData> dataList = new ArrayList<>();dataList.add(new UserData("Alice", 25, "alice@example.com"));dataList.add(new UserData("Bob", 30, "bob@example.com"));dataList.add(new UserData("Charlie", 28, "charlie@example.com"));// 使用 EasyExcel 写入 Excel 文件EasyExcel.write(filePath, UserData.class).sheet("Sheet1").doWrite(dataList);}
}

读取excel(xls,xlsx)

public class EasyReadExcelDemo {public static void main(String[] args) {String filePath = ExcelConstant.EE_EXCEL_PATH_XLSX_BIG;// 使用 EasyExcel 读取 Excel 文件EasyExcel.read(filePath, UserData.class, new UserDataListener()).sheet().doRead();}public static class UserDataListener extends AnalysisEventListener<UserData> {private List<UserData> dataList = new ArrayList<>();@Overridepublic void invoke(UserData data, AnalysisContext context) {dataList.add(data);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 在这里可以对 dataList 中的数据进行处理,比如保存到数据库或其他操作for (UserData userData : dataList) {System.out.println(userData.getName() + "\t" + userData.getAge() + "\t" + userData.getEmail());}}}
}

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

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

相关文章

Vben Admin学习笔记

Modal 弹窗 modal弹窗一般作为单文件组件被引用&#xff0c;下面是两段示例代码&#xff1a; 弹窗文件 Modal.vue // Modal.vue <template><BasicModal v-bind"$attrs" title"Modal Title" :helpMessage"[提示1, 提示2]">Modal I…

【PostgreSQL内核学习(九)—— 查询执行(数据定义语句执行)】

数据定义语句执行 概述数据定义语句执行流程执行示例 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在适用的情况下注明引用来源。 本文主要参考了《PostgresSQL…

ES6 模块编程(新思路方便复习笔记)

文章目录 ES6 模块编程(新思路方便复习笔记)介绍需求说明思路分析/图解代码实现创建common.js创建use_common.js 其它导出形式--直接导出创建common2.js创建use_common2.js 其它导出形式--默认导出创建common3.js创建use_common3.js--导入默认导出模块/数据注意事项和使用细节导…

【应用】Asible自动化运维工具的应用与常用命令

ansible自动化运维工具 一、ansible 的概述1. ansible 的概念2. ansible 的特性 二、ansible 的部署与命令1. ansible 的部署1.1 服务器ip地址设置1.2 ansible 服务器部署 2. ansible 命令行模块2.1 command 模块2.2 shell 模块2.3 cron 模块2.4 user 模块2.5 group 模块2.6 co…

中国农业大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 中国农业大学&#xff08;B-&#xff09;考研难度&#xff08;☆☆☆&#xff09; 中国农业大学计算机考研招生学院是信息与电气工程学院。目前均已出拟录取名单。 中国农业大学信息与电气工程学院&#xff0c;起源于…

使用EasyPoi实现Excel的按模板样式导出

1&#xff0c;横向遍历 #fe 使用#fe命令可以实现集合数据的横向拓展&#xff0c;比如模板代码是 {{#fe:maths t.score}}导出的excel里面就会显示会自当前列&#xff0c;向右拓展&#xff0c;效果可参见下面的导出文件截图 2&#xff0c;横向遍历值 v_fe 使用v_fe命令可以实现…

ROS前驱前转小车仿真(2D)项目

文章目录 一.官方网址1.ROS官网2.urdf-模型3.rviz-数据可视化4.gazebo-仿真环境5.gmapping-建图6.navigation-导航 二.文件框架三.启动顺序0.依赖包的安装1.手动控制的启动顺序2.建图的启动顺序3.导航的启动顺序 四.urdf-模型文件1.ackermann.xacro-轮子传动的配置2.common_pro…

MAC 推送证书不受信任

配置推送证书的时候&#xff0c;一打开就变成不受信任&#xff0c;搜了很多解决版本。 由于苹果修改相关规定&#xff0c;推送证书 打开Apple PKI - Apple 下载AppleWWDRCA文件&#xff0c;选择G4,双击安装之后&#xff0c;证书已经变为受信任。 AppleWWDRCA(Apple Worldwid…

仿VScode MDK背景配色方案

效果如果所示 操作方法&#xff1a;备份后修改~/UV4文件夹下的global.prop&#xff0c;用以下的代码代替。 # properties for all file types indent.automatic1 virtual.space0 view.whitespace0 view.endofline0 code.page936 caretline.visible1 highlight.matchingbraces1…

【数据结构】链表是否有环相关问题

文章目录 快指针走3、4、5步甚至更多可以吗为什么快慢指针一定在入口点相遇![在这里插入图片描述](https://img-blog.csdnimg.cn/ba346dbc9fee425dbb895ae2962e99ce.png) 快指针走3、4、5步甚至更多可以吗 部分情况下可以。 如果这样&#xff0c;相对&#xff08;追及&#xf…

tauri在github上进行自动更新打包并发版过程,实战操作避坑

从网上找了很多很多的文章&#xff0c;结果还是入坑了&#xff0c;一个问题找了一天才解决&#xff1a; Error A public key has been found, but no private key. Make sure to set TAURI_PRIVATE_KEY environment variable. 596 ELIFECYCLE  Command failed with exit code…

智慧消防:如何基于视频与智能分析技术搭建可视化风险预警平台?

一、背景分析 消防安全是一个重要的话题&#xff0c;涉及到每个人的生活和安全。每年都会发生大量的火灾&#xff0c;给人们带来极大的危害&#xff0c;摧毁了大量的财产&#xff0c;甚至造成了可怕的人员伤亡。而消防安全监督管理部门人员有限&#xff0c;消防安全监管缺乏有…

SVN - 记录一下无法提交代码 提示:被锁定(locked)

今天遇到一个问题&#xff0c;svn 在提交代码的时候出现了svn is already locked&#xff0c;导致代码无法提交&#xff08;commit&#xff09;和更新&#xff08;update&#xff09; 主要报错如下&#xff1a; 解决方法&#xff1a; 然后点击 Clean up 选中一下选项&#xff…

Linux centos7.x系统 下没有ens33 网卡的解决方案

一、背景 安装完windows11 Centos7.9 版本的双系统之后 , 启动Centos7.9时发现没有网卡信息 , 只有ifcfg-lo网卡的信息 , 这个时候就证明没有网卡信息&#xff0c;或者网卡驱动不匹配(我这里是没有网卡)&#xff0c;所以我们要重新安装 , 安装步骤如下 : 二、安装步骤 1.查…

PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 药品管理系统 是一套完善的web设计系统,系统采用smarty框架进行开发设计&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP 药店管理系统mysql数据库web结构apache计 下载地址…

开发一个简单的数据库路由进行分库分表

今天我们来看看一个简单的数据库路由组件要怎么开发出来&#xff0c;这篇文章分为几个步骤进行介绍&#xff0c;分别为&#xff1a; 什么是数据库路由 路由组件的作用为什么要自研组件需要用到什么技术 整体的业务流程主要代码 介绍 数据库路由的作用 使用数据库路由是在业…

产品解读|有了JMeter,为什么还需要MeterSphere?

提起JMeter&#xff0c;相信大部分的测试人员应该都很熟悉。JMeter因其小巧轻量、开源&#xff0c;加上支持多种协议的接口和性能测试&#xff0c;在测试领域拥有广泛的用户群体。一方面&#xff0c;测试人员会将其安装在个人的PC上&#xff0c;用以满足日常测试工作的需要&…

【SpringCloud Alibaba】(一)微服务介绍

此专栏内容皆来自于【冰河】的《SpringCloud Alibaba 实战》文档。 1. 专栏介绍 我们先来看看《SpringCloud Alibaba实战》专栏的整体结构吧&#xff0c;先上图 从上图&#xff0c;大家可以看到&#xff0c;专栏从整体上分为十个大的篇章&#xff0c;分别为 专栏设计、微服务…

【Git】

学习来自于&#xff1a; 女朋友乱用Git&#xff0c;差点把我代码删了。。。 一些常用的Git 知识点整理 关于Git这一篇就够了 Git基本命令大全 30分钟精通Git&#xff0c;学不会来找我 Git 版本管理 | 莫烦PYTHON Git 代码版本管理教程 文章目录 【前言】集中式与分布式的…

Jmeter配置起来太繁琐?试试RunnerGo

在用jmeter做性能测试时想看完整一点的测试报告&#xff0c;想配置阶梯模式来压测&#xff0c;想配置不同的接口并发这些都需要安装插件并且影响机器性能&#xff0c;想做自动化测试还得放到jenkins&#xff0c;这些配置起来太繁琐。今天给大家推荐一款测试平台RunnerGo&#x…