提供2种方法读取:
1.根据指定的开始和结束行数读取返回结果,结果格式为List<Map<String, Object>>
2.根据指定的开始和结束行数读取返回结果,结果格式为List<POJO(传入的实体类)>
请根据实际内存堆可用大小进行读取,太多可进行分段读取(类似分页的原理)

读取Excel所需要的几个类

1.在pom.xml加上依赖

</dependencies><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency>
</dependencies>

2.ExcelPOJO实体类

package com.cly.utils.Excel;/*** @author : CLy* @ClassName : ExcelPOJO* @date : 2020/7/9 17:13* 实体类所有成员变量都需要有GET,SET方法* 所有成员变量都要加上注解@excelRescoure(value = "?"),?为Excel真实列名,必须一一对应* @excelRescoure(value = "?"),?可为空,需要用到才赋值* 成员变量目前只允许String,Double,Interge,Float**/public class ExcelPOJO  {public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPasswork() {return passwork;}public void setPasswork(String passwork) {this.passwork = passwork;}public String getLook() {return look;}public void setLook(String look) {this.look = look;}@excelRescoure(value = "XM")private  String name;@excelRescoure(value = "SFZH")private  String passwork;@excelRescoure()private  String look;@Overridepublic String toString(){return "name:"+this.getName()+",passwork:"+this.getPasswork()+",look:"+this.getLook();}public ExcelPOJO() {}
}

3.@interface自定义注解(用于实体类读取)

package com.cly.utils.Excel;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author : CLy* @ClassName : myRescoure* @date : 2020/7/10 9:31**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface excelRescoure {String value() default "";//默认为空
}

4.excelRead类(读取Excel数据类)有很多冗余的代码,可抽离出来

package com.cly.utils.Excel;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.xml.transform.Source;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.*;
import java.text.DecimalFormat;
import java.util.*;/*** @author : CLy* @ClassName : excelRead* @date : 2020/7/9 11:08**/
public class excelRead {//日志输出private static Logger logger = LoggerFactory.getLogger(excelRead.class);//定义excel类型private static final String XLS = "xls";private static final String XLSX = "xlsx";/*** 根据文件后缀名类型获取对应的工作簿对象* @param inputStream 读取文件的输入流* @param fileType    文件后缀名类型(xls或xlsx)* @return 包含文件数据的工作簿对象*/private static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {//用自带的方法新建工作薄Workbook workbook = WorkbookFactory.create(inputStream);//后缀判断有版本转换问题//Workbook workbook = null;//if (fileType.equalsIgnoreCase(XLS)) {//    workbook = new HSSFWorkbook(inputStream);//} else if (fileType.equalsIgnoreCase(XLSX)) {//    workbook = new XSSFWorkbook(inputStream);//}return workbook;}/*** 将单元格内容转换为字符串* @param cell* @return*/private static String convertCellValueToString(Cell cell) {if (cell == null) {return null;}String returnValue = null;switch (cell.getCellType()) {case NUMERIC:   //数字Double doubleValue = cell.getNumericCellValue();// 格式化科学计数法,取一位整数,如取小数,值如0.0,取小数点后几位就写几个0DecimalFormat df = new DecimalFormat("0");returnValue = df.format(doubleValue);break;case STRING:    //字符串returnValue = cell.getStringCellValue();break;case BOOLEAN:   //布尔Boolean booleanValue = cell.getBooleanCellValue();returnValue = booleanValue.toString();break;case BLANK:     // 空值break;case FORMULA:   // 公式returnValue = cell.getCellFormula();break;case ERROR:     // 故障break;default:break;}return returnValue;}/*** 处理Excel内容转为List<Map<String,Object>>输出* workbook:已连接的工作薄* StatrRow:读取的开始行数(默认填0,0开始,传过来是EXcel的行数值默认从1开始,这里已处理减1)* EndRow:读取的结束行数(填-1为全部)* ExistTop:是否存在头部(如存在则读取数据时会把头部拼接到对应数据,若无则为当前列数)*/private static List<Map<String, Object>> HandleData(Workbook workbook, int StatrRow, int EndRow, boolean ExistTop) {//声明返回结果集resultList<Map<String, Object>> result = new ArrayList<>();//声明一个Excel头部函数ArrayList<String> top = new ArrayList<>();//解析sheet(sheet是Excel脚页)/***此处会读取所有脚页的行数据,若只想读取指定页,不要for循环,直接给sheetNum赋值,脚页从0开始(通常情况Excel都只有一页,所以此处未进行进一步处理)*/for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {Sheet sheet = workbook.getSheetAt(sheetNum);// 校验sheet是否合法if (sheet == null) {continue;}//如存在头部,处理头部数据if (ExistTop) {int firstRowNum = sheet.getFirstRowNum();Row firstRow = sheet.getRow(firstRowNum);if (null == firstRow) {logger.warn("解析Excel失败,在第一行没有读取到任何数据!");}for (int i = 0; i < firstRow.getLastCellNum(); i++) {top.add(convertCellValueToString(firstRow.getCell(i)));}}//处理Excel数据内容int endRowNum;//获取结束行数if (EndRow == -1) {endRowNum = sheet.getPhysicalNumberOfRows();} else {endRowNum = EndRow <= sheet.getPhysicalNumberOfRows() ? EndRow : sheet.getPhysicalNumberOfRows();}//遍历行数for (int i = StatrRow - 1; i < endRowNum; i++) {Row row = sheet.getRow(i);if (null == row) {continue;}Map<String, Object> map = new HashMap<>();//获取所有列数据for (int y = 0; y < row.getLastCellNum(); y++) {if (top.size() > 0) {if (top.size() >= y) {map.put(top.get(y), convertCellValueToString(row.getCell(y)));} else {map.put(String.valueOf(y + 1), convertCellValueToString(row.getCell(y)));}} else {map.put(String.valueOf(y + 1), convertCellValueToString(row.getCell(y)));}}result.add(map);}}return result;}/*** 方法一* 根据行数和列数读取Excel* fileName:Excel文件路径* StatrRow:读取的开始行数(默认填0)* EndRow:读取的结束行数(填-1为全部)* ExistTop:是否存在头部(如存在则读取数据时会把头部拼接到对应数据,若无则为当前列数)* 返回一个List<Map<String,Object>>*/public static List<Map<String, Object>> ReadExcelByRC(String fileName, int StatrRow, int EndRow, boolean ExistTop) {//判断输入的开始值是否少于等于结束值if (StatrRow > EndRow && EndRow != -1) {logger.warn("输入的开始行值比结束行值大,请重新输入正确的行数");List<Map<String, Object>> error = null;return error;}//声明返回的结果集List<Map<String, Object>> result = new ArrayList<>();//声明一个工作薄Workbook workbook = null;//声明一个文件输入流FileInputStream inputStream = null;try {// 获取Excel后缀名,判断文件类型String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);// 获取Excel文件File excelFile = new File(fileName);if (!excelFile.exists()) {logger.warn("指定的Excel文件不存在!");return null;}// 获取Excel工作簿inputStream = new FileInputStream(excelFile);workbook = getWorkbook(inputStream, fileType);//处理Excel内容result = HandleData(workbook, StatrRow, EndRow, ExistTop);} catch (Exception e) {logger.warn("解析Excel失败,文件名:" + fileName + " 错误信息:" + e.getMessage());} finally {try {if (null != workbook) {workbook.close();}if (null != inputStream) {inputStream.close();}} catch (Exception e) {logger.warn("关闭数据流出错!错误信息:" + e.getMessage());return null;}}return result;}/**==============================================================================================================================**//*** 方法二* 根据给定的实体类中赋值的注解值读取Excel* fileName:Excel文件路径* StatrRow:读取的开始行数(默认填0)* EndRow:读取的结束行数(填-1为全部)* Class<T>:传过来的实体类类型* 返回一个List<T>:T为实体类*/public static List<Object> ReadExcelByPOJO(String fileName, int StatrRow, int EndRow, Class t) throws InvocationTargetException, IntrospectionException, InstantiationException, IllegalAccessException, NoSuchFieldException {//判断输入的开始值是否少于等于结束值if (StatrRow > EndRow && EndRow != -1) {logger.warn("输入的开始行值比结束行值大,请重新输入正确的行数");List<Object> error = null;return error;}//声明返回的结果集List<Object> result = new ArrayList<>();//声明一个工作薄Workbook workbook = null;//声明一个文件输入流FileInputStream inputStream = null;try {// 获取Excel后缀名,判断文件类型String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);// 获取Excel文件File excelFile = new File(fileName);if (!excelFile.exists()) {logger.warn("指定的Excel文件不存在!");return null;}// 获取Excel工作簿inputStream = new FileInputStream(excelFile);workbook = getWorkbook(inputStream, fileType);//处理Excel内容result = HandleDataPOJO(workbook, StatrRow, EndRow, t);} catch (Exception e) {logger.warn("解析Excel失败,文件名:" + fileName + " 错误信息:" + e.getMessage());} finally {try {if (null != workbook) {workbook.close();}if (null != inputStream) {inputStream.close();}} catch (Exception e) {logger.warn("关闭数据流出错!错误信息:" + e.getMessage());return null;}}return result;}/*** 处理Excel内容转为List<T>输出* workbook:已连接的工作薄* StatrRow:读取的开始行数(默认填0,0开始,传过来是EXcel的行数值默认从1开始,这里已处理减1)* EndRow:读取的结束行数(填-1为全部)* Class<T>:所映射的实体类*/private static <t> List<Object> HandleDataPOJO(Workbook workbook, int StatrRow, int EndRow, Class<?> t) throws IntrospectionException, NoSuchFieldException, IllegalAccessException, InstantiationException, InvocationTargetException, ClassNotFoundException {//声明返回的结果集List<Object> result = new ArrayList<Object>();//解析sheet(sheet是Excel脚页)for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {Sheet sheet = workbook.getSheetAt(sheetNum);// 校验sheet是否合法if (sheet == null) {continue;}//获取头部数据//声明头部数据数列对象ArrayList<String> top = new ArrayList<>();//获取Excel第一行数据int firstRowNum = sheet.getFirstRowNum();Row firstRow = sheet.getRow(firstRowNum);if (null == firstRow) {logger.warn("解析Excel失败,在第一行没有读取到任何数据!");return null;}for (int i = 0; i < firstRow.getLastCellNum(); i++) {top.add(convertCellValueToString(firstRow.getCell(i)));}//获取实体类的成原变量Map<String, Object> POJOfields = getPOJOFieldAndValue(t);//判断所需要的数据列Map<String, Object> exceltoPOJO = new HashMap<>();for (int i = 0; i < top.size(); i++) {if (POJOfields.get(top.get(i)) != null && !"".equals(POJOfields.get(top.get(i)))) {exceltoPOJO.put(String.valueOf(i), POJOfields.get(top.get(i)));}}/*处理Excel数据内容*/int endRowNum;//获取结束行数if (EndRow == -1) {endRowNum = sheet.getPhysicalNumberOfRows();} else {endRowNum = EndRow <= sheet.getPhysicalNumberOfRows() ? EndRow : sheet.getPhysicalNumberOfRows();}List<Map<String, Object>> mapList = new ArrayList<>();//遍历行数for (int i = StatrRow - 1; i < endRowNum; i++) {Row row = sheet.getRow(i);if (null == row) {continue;}//获取需要的列数据t texcel = (t) t.newInstance();for (Map.Entry<String, Object> map : exceltoPOJO.entrySet()) {//获取Exceld对应列的数据String celldata = convertCellValueToString(row.getCell(Integer.parseInt(map.getKey())));//使用发射//获取实体类T中指定成员变量的对象PropertyDescriptor pd = new PropertyDescriptor((String) map.getValue(), texcel.getClass());//获取成员变量的set方法Method method = pd.getWriteMethod();//判断成员变量的类型Field field = texcel.getClass().getDeclaredField((String) map.getValue());String object = field.getGenericType().getTypeName();if (object.endsWith("String")) {//执行set方法method.invoke(texcel, celldata);}if (object.endsWith("Double")) {Double middata = Double.valueOf(celldata);//执行set方法method.invoke(texcel, middata);}if (object.endsWith("Float")) {Float middata = Float.valueOf(celldata);//执行set方法method.invoke(texcel, middata);}if (object.endsWith("Integer")) {Integer middata = Integer.parseInt(celldata);//执行set方法method.invoke(texcel, middata);}}result.add(texcel);}}return result;}/*** 获取对应的实体类成员* */private static Map<String, Object> getPOJOFieldAndValue(Class T) {//声明返回结果集Map<String, Object> result = new HashMap<>();Field[] fields = T.getDeclaredFields();//获取属性名if (fields != null) {for (Field field : fields) {excelRescoure Rescoure = field.getAnnotation(excelRescoure.class);if (Rescoure.value() != null && !"".equals(Rescoure.value())) {result.put(Rescoure.value(), field.getName());}}} else {logger.warn("实体类:" + T + "不存在成员变量");return null;}return result;}
}

5.测试类

package com.cly.utils.Excel;import java.util.*;/*** @author : CLy* @ClassName : Readtest* @date : 2020/7/9 16:31**/
public class Readtest {public static void main(String[] args) throws Exception {/** 方法一* fileName:Excel文件路径* StatrRow:读取的开始行数(默认填0)* EndRow:读取的结束行数(填-1为全部)* ExistTop:是否存在头部(如存在则读取数据时会把头部拼接到对应数据作为KEY,若无则KEY为当前列数)*/List<Map<String,Object>> result =excelRead.ReadExcelByRC("D:.xls",2,10,false);System.out.println(result.size());System.out.println(result);/*** 方法二* ReadExcelByPOJO(String fileName, int StatrRow, int EndRow, Class t)* fileName:Excel文件路径* StatrRow:读取的开始行数(默认填0)* EndRow:读取的结束行数(填-1为全部)* Class<T>:传过来的实体类类型*/List<Object> result2 = excelRead.ReadExcelByPOJO("D:.xls",2,10,ExcelPOJO.class);System.out.println(result2.size());System.out.println(result2);}
}

6.运行结果和说明
exce表格数据

方法一的运行结果
1.ture:key为列名


2.false:key为第几列列数

方法二的运行结果
实体类的所有成员变量一定要加上自定义注释@excelRescoure,不然会报错

SpringBoot实现Excel读取相关推荐

  1. 利用Spring-Boot解析Excel、用Java分析Excel、告别手动输入用程序读取Excel

    利用Spring-Boot解析Excel.用Java分析Excel.告别手动输入用程序读取Excel 一.资源 java读取Excel文件 二.修改 (一)中的代码中的 import service. ...

  2. SpringBoot使用Workbook读取excel中内容

    SpringBoot使用Workbook读取excel中内容 maven文件中导入依赖 获取excel文件 FileInputStream fileInputStream = new FileInpu ...

  3. 基于springboot架构的读取excel 图片并自动上传

    基于springboot架构的读取excel 图片并自动上传 excel 图片上传 页面准备 comment.html 逻辑处理准备 控制类CommentController.java 接口类ICom ...

  4. springboot整合poi读取数据库数据和图片动态导出excel

    springboot整合poi读取数据库数据和图片动态导出excel 第一次操作 话不多说就直接上代码 实现代码 需要的依赖 <dependency><groupId>org. ...

  5. 【vue+springboot】excel模板下载、导入功能实现

    基于VUE+SpringBoot实现excel模板下载.导入功能 背景 最近在工作中经常遇到批量导入的功能,而且前端还要提示导入成功几条.失败几条.哪一条数据重复.是哪一条导入的数据出现问题等,抽空写 ...

  6. EasyExcel专题(一) Excel 读取、写入、上传和下载

    一.将10万条数据从Excel读取出来 读取支持多标题,我们只需要指定最后一行的标题的行号即可,例如上述excel标题的行号为1,因此需要设置headRowNumber为1. 定义User 类,使用U ...

  7. Springboot之Excel表格导出

    Springboot之Excel表格导出 表格导出使用的还是POI,POI的介绍请查看 https://blog.csdn.net/qq_36654629/article/details/901729 ...

  8. Apache POI和EasyExcel 第六集:Apache POI的Excel读取单元格中的计算公式

    Apache POI和EasyExcel 第六集:Apache POI的Excel读取单元格中的计算公式 一.资源 代码实现中的带有计算公式的Excel(xls) 链接:https://pan.bai ...

  9. Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据

    Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据 一.资源 什么是Apache POI Apache POI 不同类型的数据的表格(xls) 链接: ...

最新文章

  1. 成为顶级CIO ,应该怎么做?
  2. 架构师必须掌握的 10 条设计原则
  3. Spring AOP技术(基于AspectJ)的XML开发
  4. mysql 工时统计_有如下数据,要统计1月3号工时不足8小时的员工姓名及总工时,该sql语句该怎么写(用的mysql哈)...
  5. Qt Package Project 打包发布程序
  6. struts2中的constant配置详解
  7. python 除数总是提示为0_Python错误的处理方法
  8. 让Mootools的语法结构像Jquery那样
  9. 关于ionic中几个问题
  10. 用云计算机,云计算在生活中的应用
  11. 【IoT】产品设计:关于专利申请,这篇文章就够了
  12. html创建表格没有网格线,excel里面的电子表格没有了网格线如何解决?
  13. DID会固定年份吗_互助问答第31期:固定效应与随机效应选择和面板数据处理
  14. DeepFool公式理解
  15. 移动硬盘格式化后还能恢复数据吗 格式化的移动硬盘数据能恢复吗
  16. SylixOS学习三—— SylixOS的引导与安装2
  17. 100的阶层真的算不出来吗?
  18. NDK开发入门终极教程
  19. 华为鸿蒙HarmonyOS,华为鸿蒙HarmonyOS 2.0
  20. Centos8怎么关闭终端响铃? Centos系统取消终端响铃的方法

热门文章

  1. 历史影像再来一波(能到70年代、80年代的历史影像数据)
  2. vim从其它地方赋值粘贴时自动换行添加缩进解决办法
  3. 上传文件、下载文件、数据导出excel表格整理模板
  4. 统计分析---多重共线性
  5. 原始字符串(Raw String)
  6. 软工大牛Rijnard van Tonder 和 Claire Le Goues及其顶会论文解读
  7. python用amd还是intel_计算机专业 CPU 应该用 AMD 还是 Intel?
  8. 粒子的散射模拟matlab程序,非常好的球粒子Mie散射matlab仿真
  9. 打印菱形(C语言 水一下)
  10. java 流量攻击_如何防御网站被ddos攻击 首先要了解什么是流量攻击