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;起源于…

SkyWalking链路追踪-Collector(收集器)

Collector&#xff08;收集器&#xff09; SkyWalking的Collector&#xff08;收集器&#xff09;是SkyWalking链路追踪的核心组件之一。它负责接收来自各个Agent的追踪数据&#xff0c;并将其存储到数据存储器&#xff08;如数据库&#xff09;中。具体来说&#xff0c;Colle…

微信小程序之富文本特殊处理

文章目录 前言一、video的处理二、img的处理总结 前言 小程序中使用富文本编辑器&#xff0c;由于rich-text受限 部分富文本内容无法渲染或排版错乱。以img和video为例&#xff0c;处理起来让人头疼。网上各种长篇大论&#xff0c;实际上没有任何帮助。接下来我们就一起聊聊im…

React + Typescript + Antd:封装通用的字典组件DXSelect

在开发中,我们经常遇到这样的场景,在表单中,有个下拉框,选择对应的数据。 那么这个下拉框的选项,就是字典。一搬的做法是,通过antd的Select来实现,代码如下: <Select defaultValue={defaultValue} style={styles} {...otherProps}>{options.map((

使用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…

如何解决过拟合/欠拟合问题

文章目录 1. 什么是过拟合/欠拟合2. 如何防止过拟合3. 如何防止欠拟合 1. 什么是过拟合/欠拟合 过拟合&#xff1a;模型在训练集上表现很好&#xff0c;但在测试集上表现很差&#xff1b;即模型的泛化能力差。欠拟合&#xff1a;模型在训练集上表现很差&#xff0c;没有测试的…

仿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…

Nginx专题--反向代理(未完成)

反向代理   正向代理&#xff1a;如果把局域网外的 Internet 想象成一个巨大的资源库&#xff0c;则局域网中的客户端要访问 Internet&#xff0c;则需要通过代理服务器来访问&#xff0c;这种代理服务就称为正向代理。 反向代理&#xff1a;其实客户端对代理是无感知的&…

linux下cups 毫秒级频繁自启,导致服务瘫痪,无法使用

主要是没法停止了&#xff0c;&#xff0c;即使stop&#xff0c;它还是会自己重启&#xff0c;&#xff0c;&#xff0c; 所以直接破坏cups.service文件&#xff0c;然后restart&#xff0c;就会发现启动失败了。。 roothighguard-F300-G30:~# cat /lib/systemd/system/cups.s…

8 Linux实操篇-用户管理

8 Linux实操篇-用户管理 文章目录 8 Linux实操篇-用户管理8.1 添加用户8.2 指定/修改密码8.3 删除用户8.4 切换用户8.5 查询用户信息/查看用户8.6 用户组8.7 用户和组相关文件 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。可能会用到的资料有如下所示&am…

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…

k8s exam

Pause 容器是 Pod 中的第一个启动的容器&#xff0c;其他所有的用户容器都是其子进程当 Pod 被从节点中删除时&#xff0c;与之关联的 emptyDir 中的数据也将被永久删除。持久存储用PV&#xff0c;PVCService 资源定义了如何访问应用&#xff0c;但实际的网络流量管理和路由是由…

【树莓派】用于处理 I2C、SPI 和 UART 的C++库

一、说明 Raspberry Pi 是一款单板计算机&#xff0c;现在有 4 个修订版和一个简约的零变体。它是不同项目的热门选择&#xff0c;因为它体积小&#xff0c;功耗高&#xff0c;处理速度快&#xff0c;并且是一台完整的基于Linux的计算机。 连接多台单板计算机和/或微控制器的一…