读取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 节点的日志&…...

搜索与图论:染色法判定二分图
将所有点分成两个集合,使得所有边只出现在集合之间,就是二分图 二分图:一定不含有奇数个点数的环;可能包含长度为偶数的环, 不一定是连通图 染色可以使用1和2区分不同颜色,用0表示未染色 遍历所有点&…...

磁场设备主要有哪些
磁学是物理学最古老的研究领域之一,目前仍然充满了生机活力。对于磁性物理的科学研究、磁性材料相关的探索来说,磁场设备必不可少,因为在外加磁场的作用下,样品会表现出特殊的物理性质,并带来了巨大的应用前景…...

【wespeaker】模型ECAPA_TDNN介绍
本次主要介绍开源项目wespeaker模型介绍 1. 模型超参数 model_args: feat_dim: 80 embed_dim: 192 pooling_func: “ASTP” projection_args: project_type: “softmax” # add_margin, arc_margin, sphere, softmax scale: 32.0 easy_margin: False 2. 模型结构 2.1 Layer…...

GPT技术的广泛使用
GPT技术的广泛使用确实引发了一些关于其潜在影响的讨论,包括可能导致某些职业失业以及对一些互联网公司构成竞争压力的问题。然而,这个问题涉及到多个方面,而且不容易一概而论。 潜在影响: 自动化任务: GPT等自然语言…...

银河麒麟V10安装MySQL8.0.28并实现远程访问
参考资料: 银河麒麟V10安装MySQL8.0.28并实现远程访问-数据库运维技术服务 银河麒麟高级服务器操作系统V10安装mysql数据库_麒麟v10安装mysql-CSDN博客...

[AUTOSAR][诊断管理][ECU][$27] 安全访问
文章目录 一、简介$27服务有何作用,为什么要有27服务呢?功能描述应用场景安全解锁基本原理服务请求服务响应Verify Key负响应NRC支持二、常见Bug大揭秘三、示例代码uds27_security_access.c一、简介 $27服务有何作用,为什么要有27服务呢? 功能描述 根据ISO14119-1标准中…...

Android Studio编译旧的app代码错误及解决方法
‘android.injected.build.density’ is deprecated. The option ‘android.injected.build.density’ is deprecated. It was removed in version 8.0 of the Android Gradle plugin. Density property injection from Android Studio has been removed. 解决 app/build.gr…...

Docker的架构与自制镜像的发布
一. Docker 是什么 Docker与自动化测试及其测试实践 大家都知道虚拟机吧,windows 上装个 linux 虚拟机是大部分程序员的常用方案。公司生产环境大多也是虚拟机,虚拟机将物理硬件资源虚拟化,按需分配和使用,虚拟机使用起来和真实操…...

嵌入式系统中C++ 类的设计和实现分析
C代码提供了足够的灵活性,因此对于大部分工程师来说都很难把握。 本文介绍了写好C代码需要遵循的10个最佳实践,并在最后提供了一个工具可以帮助我们分析C代码的健壮度。 原文:10 Best practices to design and implement a C class。 1. 尽…...

【torch高级】一种新型的概率学语言pyro(02/2)
前文链接:【torch高级】一种新型的概率学语言pyro(01/2) 七、Pyro 中的推理 7.1 背景:变分推理 引言中的每项计算(后验分布、边际似然和后验预测分布)都需要执行积分,而这通常是不可能的或计算…...