读取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();}
}

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

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

相关文章

太极v14.0.4 免ROOT用Xposed

一个帮助你免 Root、免解锁免刷机使用 Xposed 模块的 APP 框架。 模块通过它改变系统和应用的行为&#xff0c;既能以传统的 Root/ 刷机方式运作&#xff0c; 也能免 Root/ 免刷机运行&#xff1b;并且它支持 Android 5.0 ~ 11。 简单来说&#xff0c;太极就是个 Xposed 框架…

2024线性代数复习——矩阵代数

相似矩阵&#xff1a;存在可逆矩阵 P P P&#xff0c;使得 P − 1 A P B P^{-1} A PB P−1APB&#xff0c;则称矩阵 A A A&#xff0c; B B B 相似&#xff0c;特征值相等。注意只有相似矩阵 B B B 是对角阵&#xff0c;我们才说它是可以相似对角化的。 A A A 可以相似对角…

vue 复杂的流程图实现--antv/g6

可以先看下对应的文档&#xff1a;G6 Demos - AntV npm install --save antv/g6 实现如图&#xff1a; <template><div class"drawflow"><div id"mountNode"></div></div> </template> <script> import G6 fr…

Qwt QwtPlotMarker标记类详解

1.概述 QwtPlotMarker类是Qwt绘图库中用于在图表上绘制标记的类。标记可以是垂直或水平线、直线、文本或箭头等。它可用于标记某个特定的位置、绘制参考线或注释信息。 以下是类继承关系图&#xff1a; 2.常用方法 设置标记的坐标。传入x和y坐标值&#xff0c;标记将被放置在…

【23种设计模式】接口隔离原则

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

电脑视频怎么转音频mp3

如果你在电脑上观看视频时喜欢上某个片段的背景音乐&#xff0c;且想将喜欢的背景音乐制作为手机铃声。我是建议你将此视频转换为 MP3 格式&#xff0c;因为 MP3 几乎与所有设备相兼容&#xff0c;让你可以在不同设备上不受限制地去聆听它。那该如何转换呢&#xff1f;无需担心…

vue路径中“@/“代表什么

举例&#xff1a; <img src"/../static/imgNew/adv/tupian.jpg"/>其中&#xff0c;/是webpack设置的路径别名&#xff0c;代表什么路径&#xff0c;要看webpack的build文件夹下webpack.base.conf.js里面对于是如何配置&#xff1a; 上图中代表src,上述代码就…

RabbitMQ 链接管理-发布者-消费者

RabbitMQ连接管理器 using RabbitMQ.Client; using System; public class RabbitMQConnectionManager { private readonly IConnectionFactory _connectionFactory; private IConnection _connection; public RabbitMQConnectionManager(string hostName) { …

LayerUI中按钮点击一次,触发了两次事件

form.on("submit(clericalServices)", function (data) {console.log("1111111");var getTpl clericalServicesT.innerHTML;laytpl(getTpl).render({}, function (html) {$("#type1Scope").append(html);});return false})点击一次&#xff0c;…

构建自动化测试环境:使用Docker和Selenium!

随着软件开发的日益复杂和迭代速度的加快&#xff0c;自动化测试被越来越广泛地应用于软件开发流程中。它能够提高测试效率、减少测试成本&#xff0c;并保证软件质量的稳定性。在构建自动化测试环境方面&#xff0c;Docker 和 Selenium 是两个非常有用的工具。下面将介绍如何使…

Python分享之多进程探索 (multiprocessing包)

在初步了解Python多进程之后&#xff0c;我们可以继续探索multiprocessing包中更加高级的工具。这些工具可以让我们更加便利地实现多进程。 进程池 进程池 (Process Pool)可以创建多个进程。这些进程就像是随时待命的士兵&#xff0c;准备执行任务(程序)。一个进程池中可以容…

CSS外边距重叠:原理、结果

引言 CSS中的外边距是控制元素间距的重要属性之一。然而&#xff0c;当涉及到相邻元素的外边距时&#xff0c;可能会出现外边距重叠的情况&#xff0c;这可能会对页面布局产生一些意想不到的影响。本文将深入探讨什么是外边距重叠以及它可能导致的结果&#xff0c;并提供一些代…

7-4、S加减速转动实现【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线   加速角度&#xff1a;角度为90   起步速度&#xff1a;30RPM&#xff0c;   终止速度&#x…

【数智化人物展】同方有云联合创始人兼总经理江琦:云计算,引领数智化升级的动能...

江琦 本文由同方有云联合创始人兼总经理江琦投递并参与《2023中国企业数智化转型升级先锋人物》榜单/奖项评选。 数据智能产业创新服务媒体 ——聚焦数智 改变商业 在这个飞速发展的数字时代&#xff0c;我们置身于一个前所未有的机遇与挑战并存的时刻。数字化转型不再仅仅是一…

sprinbboot 2.7启动不生成日志文件

新增了一个springboot项目&#xff0c;通过idea 调试&#xff0c;并且在idea 的vm options中指定-Dlogging.configclasspath:logback-pro.xml 或者 -Dlogging.configclasspath:logback-dev.xml 都能正常生成对应的日志文件。 部署到测试环境以及生产环境&#xff0c;日志文件却…

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

jmeter疑难杂症

mac启动jmeter 进入jmeter文件夹下的bin目录 执行sh jmeter 如何线程与线程之间按照顺序执行 线程组内随机执行 选择线程组右键 >>> 添加 >>> 逻辑控制器 >>> 随机顺序控制器&#xff08;Random Order Controller&#xff09; 如何提取cookie的…

Qt中的单例模式

QT单例类管理信号和槽函数 Chapter1 Qt中的单例模式一、什么是单例模式&#xff1f;二、Qt中单例模式的实现2.1、静态成员变量2.2、静态局部变量2.3、Q_GLOBAL_STATIC 宏实例2 三、使用场景四、注意事项 Chapter2 QT单例类管理信号和槽函数一、创建单例类二、主界面添加组件三、…

golang连接池检查连接失败时如何重试

在Go中&#xff0c;可以通过使用database/sql包的DB类型的Ping方法来检查数据库连接的可用性。如果连接检查失败&#xff0c;可以选择进行重试。以下是一个简单的示例代码&#xff0c;演示了如何在连接检查失败时进行重试&#xff1a; import ("database/sql""…

图像去噪滤波算法汇总(Python)

前言 上篇文章&#xff1a;图像数据噪音种类以及Python生成对应噪音&#xff0c;汇总了常见的图片噪音以及噪音生成方法&#xff0c;主要用在数据增强上面&#xff0c;作为数据集填充的方式&#xff0c;可以避免模型过拟合。想要了解图像数据增强算法的可以去看本人所撰这篇文…