读取Excel的工具类——ExcelKit
文章目录
- ExcelKit工具类
- 1、准备工作
- 1.1、SheetInfoVo
- 1.2、BizException
- 2、读取xlsx
- 3、读取xls
- 4、完整的ExcelKit.java源码
ExcelKit工具类
1、准备工作
1.1、SheetInfoVo
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@AllArgsConstructor
@NoArgsConstructor
public class SheetInfoVo implements Serializable {/*** 读取的sheet页*/private int sheetIndex;/*** 忽略的行数*/private int ignoreRow;/*** 忽略的列数*/private int ignoreColumn;/*** 指定行(如果不指定,那么动态获取)*/private int lastRowNum;/*** 指定列(如果不指定,那么动态获取)*/private int lastCellNum;}
1.2、BizException
/*** 业务性异常类*/
public class BizException extends RuntimeException{/** 数据校验异常 */public static final String ERRORCODE_INVALID_DATA = "01";/** 当前用户没有操作权限 */public static final String ERRORCODE_UNAUTHORIZED = "02";/** 数据当前状态不允许该操作 */public static final String ERRORCODE_INVALID_STATUS = "03";/** 其他业务异常 */public static final String ERRORCODE_OTHER = "99";private final String errorCode;public BizException(String errorCode, String message) {super(message);this.errorCode = errorCode;}public BizException(String errorCode, String message, Throwable cause) {super(message, cause);this.errorCode = errorCode;}public String getErrorCode() {return errorCode;}
}
2、读取xlsx
依赖包:
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version>
</dependency>
读取方法:
/**
* 读取xlsx文件的第一个Sheet页(07)
* @param inputStream
* @return
*/
public static List<List<String>> readOneXlsxSheet(final FileInputStream inputStream, final SheetInfoVo sheetInfo) throws BizException {List<List<String>> resultList = new LinkedList<>();SheetInfoVo vo = initSheetInfo(sheetInfo);int sheetIndex = vo.getSheetIndex();int ignoreRow = vo.getIgnoreRow();int ignoreColumn = vo.getIgnoreColumn();int lastRowNum = vo.getLastRowNum();int lastColumnNum = vo.getLastCellNum();try {//poi-ooxml包XSSFWorkbook workbook= new XSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(sheetIndex);//如果有指定读取到第几行,那么按指定的来lastRowNum = lastRowNum == 0 ? sheet.getLastRowNum() : lastRowNum;for (int rowIndex = ignoreRow; rowIndex <= lastRowNum; rowIndex++) {Row row = sheet.getRow(rowIndex);if (row == null) {continue;}int lastCellNum = lastColumnNum == 0 ? row.getLastCellNum() : lastColumnNum;List<String> result = new LinkedList<>();for (int columnIndex = ignoreColumn; columnIndex < lastCellNum; columnIndex++) {Cell cell = row.getCell(columnIndex);String value = getCellValue(cell);result.add(value);}resultList.add(result);}}catch (IllegalArgumentException e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "读取的sheet页异常或读取的单元格异常,请联系IT处理");}catch (Exception e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "文件读取异常,请联系IT处理");}return resultList;
}
3、读取xls
依赖包:
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version>
</dependency>
读取文件方法:
/**
* 读取xls文件的第一个Sheet页(03)
* @param inputStream
* @return
*/
public static List<List<String>> readOneXlsSheet(FileInputStream inputStream, SheetInfoVo sheetInfo) throws BizException{List<List<String>> resultList = new LinkedList<>();SheetInfoVo vo = initSheetInfo(sheetInfo);int sheetIndex = vo.getSheetIndex();int ignoreRow = vo.getIgnoreRow();int ignoreColumn = vo.getIgnoreColumn();int lastRowNum = vo.getLastRowNum();int lastColumnNum = vo.getLastCellNum();try {//poi-ooxml包Workbook workbook= new HSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(sheetIndex);//如果有指定读取到第几行,那么按指定的来lastRowNum = lastRowNum == 0 ? sheet.getLastRowNum() : lastRowNum;for (int rowIndex = ignoreRow; rowIndex <= lastRowNum; rowIndex++) {Row row = sheet.getRow(rowIndex);if (row == null) {continue;}int lastCellNum = lastColumnNum == 0 ? row.getLastCellNum() : lastColumnNum;List<String> result = new LinkedList<>();for (int columnIndex = ignoreColumn; columnIndex < lastCellNum; columnIndex++) {Cell cell = row.getCell(columnIndex);String value = getCellValue(cell);result.add(value);}resultList.add(result);}}catch (IllegalArgumentException e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "读取的sheet页异常或读取的单元格异常,请联系IT处理");}catch (Exception e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "文件读取异常,请联系IT处理");}return resultList;
}
4、完整的ExcelKit.java源码
使用的时候切记要把包名导入,并修改导入的 BizException 和 SheetInfoVo 类路径。
使用的时候切记要把包名导入,并修改导入的 BizException 和 SheetInfoVo 类路径。
使用的时候切记要把包名导入,并修改导入的 BizException 和 SheetInfoVo 类路径。
package com.example.kit;import com.example.common.BizException;
import com.example.vo.SheetInfoVo;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;public class ExcelKit {/*** 读取Excel文件,默认读取第一个Sheet页,不跳过所有行与列* @param file* @return* @throws Exception*/public static List<List<String>> readOneSheet(File file) throws Exception {return readOneSheet(file, null);}/*** 读取Excel文件,通过sheetInfo对象,指定读取的sheet页、跳过行列标题数,甚至指定读取的行数列数数* @param file 读取的文件* @param sheetInfo 读取的形式* @return 读取到的二维 String 列表* @throws IOException* @throws BizException*/public static List<List<String>> readOneSheet(File file, SheetInfoVo sheetInfo) throws IOException, BizException {if (file == null) {throw new FileNotFoundException("读取文件不能为空!");}FileInputStream inputStream = new FileInputStream(file);String fileName = file.getName();Workbook workbook = null;if (fileName.endsWith(".xls")) {workbook = new HSSFWorkbook(inputStream);}else if (fileName.endsWith(".xlsx")) {workbook = new XSSFWorkbook(inputStream);}else {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "上传文件类型有误,请上传.xls或.xlsx的文件");}return readOneExcelSheet(workbook, sheetInfo);}public static List<List<String>> readOneExcelSheet(final Workbook workbook, final SheetInfoVo sheetInfo) throws BizException {List<List<String>> resultList = new LinkedList<>();SheetInfoVo vo = initSheetInfo(sheetInfo);int sheetIndex = vo.getSheetIndex();int ignoreRow = vo.getIgnoreRow();int ignoreColumn = vo.getIgnoreColumn();int lastRowNum = vo.getLastRowNum();int lastColumnNum = vo.getLastCellNum();try {Sheet sheet = workbook.getSheetAt(sheetIndex);//如果有指定读取到第几行,那么按指定的来lastRowNum = lastRowNum == 0 ? sheet.getLastRowNum() : lastRowNum;for (int rowIndex = ignoreRow; rowIndex <= lastRowNum; rowIndex++) {Row row = sheet.getRow(rowIndex);if (row == null) {continue;}int lastCellNum = lastColumnNum == 0 ? row.getLastCellNum() : lastColumnNum;List<String> result = new LinkedList<>();for (int columnIndex = ignoreColumn; columnIndex < lastCellNum; columnIndex++) {Cell cell = row.getCell(columnIndex);String value = getCellValue(cell);result.add(value);}resultList.add(result);}}catch (IllegalArgumentException e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "读取的sheet页异常或读取的单元格异常,请联系IT处理");}catch (Exception e) {throw new BizException(BizException.ERRORCODE_INVALID_STATUS, "文件读取异常,请联系IT处理");}return resultList;}/*** 初始化 SheetInfo* @param sheetInfo* @return*/private static SheetInfoVo initSheetInfo(final SheetInfoVo sheetInfo) {SheetInfoVo vo = new SheetInfoVo(0, 0, 0, 0, 0);if (sheetInfo == null) {vo.setSheetIndex(0);vo.setIgnoreRow(0);vo.setIgnoreColumn(0);vo.setLastRowNum(0);vo.setLastCellNum(0);}else {int sheetIndex = sheetInfo.getSheetIndex();int ignoreRow = sheetInfo.getIgnoreRow();int ignoreColumn = sheetInfo.getIgnoreColumn();int lastRowNum = sheetInfo.getLastRowNum();int lastCellNum = sheetInfo.getLastCellNum();if (isNotNullAndBigThenZero(sheetIndex)) {vo.setSheetIndex(sheetIndex);}if (isNotNullAndBigThenZero(ignoreRow)) {vo.setIgnoreRow(ignoreRow);}if (isNotNullAndBigThenZero(ignoreColumn)) {vo.setIgnoreColumn(ignoreColumn);}if (isNotNullAndBigThenZero(lastRowNum)) {vo.setLastRowNum(lastRowNum);}if (isNotNullAndBigThenZero(lastCellNum)) {vo.setLastCellNum(lastCellNum);}}return vo;}private static boolean isNotNullAndBigThenZero(Integer value) {if (value != null && value > 0) {return true;}return false;}/*** 获取单元格数据* @param cell* @return*/private static String getCellValue(Cell cell) {String value = "";if (cell == null) {return value;}switch (cell.getCellType()) {case STRING:value = cell.getRichStringCellValue().getString();break;case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {Date date = cell.getDateCellValue();if (date != null) {value = new SimpleDateFormat("yyyy-MM-dd").format(date);} else {value = "";}} else {value = getRealStringValueOfDouble(cell.getNumericCellValue());}break;case FORMULA:cell.setCellType(CellType.STRING);// 导入时如果为公式生成的数据则无值if (!cell.getRichStringCellValue().getString().equals("")) {value = cell.getRichStringCellValue().getString();} else {value = cell.getNumericCellValue() + "";}break;case BOOLEAN:value = (cell.getBooleanCellValue() == true ? "Y" : "N");break;default:value = "";break;}return value;}// 处理科学计数法与普通计数法的字符串显示,尽最大努力保持精度private static String getRealStringValueOfDouble(Double value) {String doubleStr = value.toString();//是否使用科学计数法boolean isScientificNotation = doubleStr.contains("E");if (isScientificNotation) {//很小的小数if (doubleStr.contains("E-")) {doubleStr = handleSoSmallNumber(doubleStr);}else { //很大的数doubleStr = handleSoBigNumber(doubleStr);}} else {java.util.regex.Pattern p = Pattern.compile(".0$");java.util.regex.Matcher m = p.matcher(doubleStr);if (m.find()) {doubleStr = doubleStr.replace(".0", "");}}return doubleStr;}/*** 处理科学计数法很小的数,类似0.00000000000000123456* @param value* @return*/private static String handleSoSmallNumber(String value) {StringBuffer sb = new StringBuffer();int indexOfE = value.indexOf("E-");//小数的尾巴String tail = value.substring(0, indexOfE).replace(".", "");//指数int pow = Integer.parseInt(value.substring(indexOfE + 2));//补零sb.append("0.");while (--pow > 0) {sb.append("0");}sb.append(tail);return sb.toString();}/*** 处理科学计数法很大的数,类似12345678910.123456* @param value* @return*/private static String handleSoBigNumber(String value) {StringBuffer sb = new StringBuffer();int indexOfE = value.indexOf("E");int pow = Integer.parseInt(value.substring(indexOfE + 1));int valueLength = value.substring(0, indexOfE).length();if (pow > valueLength - 2) {String head = value.substring(0, indexOfE).replace(".", "");sb.append(head);int zeroNum = pow - head.length() + 1;while (zeroNum-- > 0) {sb.append("0");}}else {String head = value.substring(0, pow + 2).replace(".", "");String tail = value.substring(pow + 2, indexOfE);sb.append(head).append(".").append(tail);}return sb.toString();}
}
相关文章:
读取Excel的工具类——ExcelKit
文章目录 ExcelKit工具类1、准备工作1.1、SheetInfoVo1.2、BizException 2、读取xlsx3、读取xls4、完整的ExcelKit.java源码 ExcelKit工具类 1、准备工作 1.1、SheetInfoVo import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import …...
vscode连接服务器一直retry
解决方法 打开vscode控制面板,输入命令remote-ssh: kill vs code server on host 选择一直连接不上的服务器端口 重新连接...
Spring Cloud Sentinel整合Nacos实现配置持久化
sentinel配置相关配置后无法持久化,服务重启之后就没了,所以整合nacos,在nacos服务持久化,sentinel实时与nacos通信获取相关配置。 使用上一章节Feign消费者服务实现整合。 版本信息: nacos:1.4.1 Sentinel 控制台 …...
STM32F4VGT6-DISCOVERY:uart1驱动
对于这款板子,官方并没有提供串口例程,只能自行添加。 一、PA9/PA10复用成串口1功能不可用 驱动测试代码如下: main.c: #include "main.h" #include <stdio.h>void usart1_init(void) {GPIO_InitTypeDef GPIO_InitStruct…...
C语言之 结构体,枚举,联合
目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 2. 位段 2.1 什么是位段 2.2位段的内存分配 2.3 位段的跨平台问题 3. 枚举 3.1 枚举类型…...
红米电脑硬盘剪切
Redmi R14 2023版固态硬盘剪切 工具准备操作结尾语 首先要说明,本文所说的操作不一定适合你的电脑,因为电子产品更新换代过快,你的硬盘不一定能剪切,在操作前一定要仔细观察硬盘的型号,是否为同款,我上了图…...
微信小程序在线预览PDF文件
需求:微信小程序在线预览PDF合同文件,加载完成后强制阅读10秒才可点击同意按钮 H5代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" cont…...
Android 工厂模式增加Type-A功能测试
Android 工厂模式增加Type-A功能测试 收到客户需求想要增加Type-A测试项来验证Type-A功能,具体功能实现参照如下: /vendor/freeme/packages/apps/FreemeFactoryTest/src/com/freeme/factory/usb/TypeAUSB.java package com.freeme.factory.usb;i…...
Web攻防06_sqlmap的使用
文章目录 参考链接: SQLMAP简介支持五种不同的注入模式 数据猜解-库表列数据权限操作引出权限:引出文件:引出命令(执行命令): 提交方法-POST&HEAD&JSONPost注入cookie注入注入请求头中(…...
C++模拟实现-----日期计算器(超详细解析,小白一看就会!)
目录 一、前言 二、日期类计算器 三、日期计算器的实现 🍎日期计算器各个接口的实现 🍐日期计算器的需求 🍉打印当前日期(并检查日期是否合理) 💦检查日期是否合理 💦日期类构造函数&#x…...
Oracle实现把B表某一字段更新到A表
1.使用SQL命令UPDATE语句。 2.使用MERGE语句。 3.使用TRIGGER触发器。 4.使用游标CURSOR和循环 使用游标和循环来将B表中的数据更新到A表中,从而实现了两个表数据的同步。例如下面的代码实现:...
CUMCM历年赛题汇总
题目来源: 全国大学生数学建模竞赛官网 注:题目和数据均可在官网下载 2021–2023年 年份题号题目2023A定日镜场的优化设计2023B多波束测线问题2023C蔬菜类商品的自动定价与补货决策2023D圈养湖羊的空间利用率2023E黄河水沙监测数据分析2022A波浪能最大…...
人间道-您到底做错了什么:正心径之您要逐渐去除外邪行为
过去的您或许在您自个身上付出,投入了巨大,重大的人力,物力,财力等各方面的重重的成本,但是呢,收获却微小的稀罕,微少的可怜啊。甚至于一个错误,就把您完全陷入到万丈深渊里面去了&a…...
Spring Boot拓展XML格式的请求和响应
在我们开发过程中,我们经常使用的参数绝大多少事HTML和JSON格式的请求和响应处理,但是我们在实际开发过程中,我们可能经历一些,比如对于XML格式的请求,我们在后端应该如何接收,并且如何将XML格式的参数变成…...
0045【Edabit ★☆☆☆☆☆】【字符数转整型】Return a String as an Integer
0045【Edabit ★☆☆☆☆☆】【字符数转整型】Return a String as an Integer language_fundamentals numbers strings Instructions Create a function that takes a string and returns it as an integer. Examples stringInt("6") // 6 stringInt("1000&q…...
数据库MySQL(六):事务
事务 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 MySQL中默认事务是自动提交的,当执行完一条DML语句时…...
比较浮点数时,我被绊倒了
📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不是…...
JVM进阶(1)
一)JVM是如何运行的? 1)在程序运行前先将JAVA代码转化成字节码文件也就是class文件,JVM需要通过类加载器将字节码以一定的方式加载到JVM的内存运行时数据区,将类的信息打包分块填充在运行时数据区; 2)但是字节码文件是JVM的一套指…...
【AICFD案例操作】汽车外气动分析
AICFD是由天洑软件自主研发的通用智能热流体仿真软件,用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程,帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…...
Hadoop 请求数据长度 Requested Data length 超过配置的最大值
一、问题 现象 Spark 任务速度变慢,也不失败。 DataNode 内存足够 CPU 负载不高 GC 时间也不长。 查看 DataNode 日志,发现有些日志出现很多 Netty RPC 超时。超时的 destination 是一个 NameNode 节点,然后查看 NameNode 节点的日志&…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
