excel导入功能

article/2025/9/8 18:04:27

------这里只是测试类------实际使用的看下面

需要用到ExcelUtils工具类

ExcelUtils的主要作用是把Excel转化成 List<List<Object>>类型的数据,方便遍历

package tech.niua.common.excelimport;import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;/*** Created by sangyinghao* Date :2022/4/26* Description : excel导入工具类* Version :1.0*/
public class ExcelUtils {private final static String excel2003L =".xls";    //2003- 版本的excelprivate final static String excel2007U =".xlsx";   //2007+ 版本的excel/*** @Description:获取IO流中的数据,组装成List<List<Object>>对象* @param in,fileName* @return* @throws IOException*/public static List<List<Object>> getListByExcel(InputStream in, String fileName) throws Exception{List<List<Object>> list = null;//创建Excel工作薄Workbook work = getWorkbook(in,fileName);if(null == work){throw new Exception("创建Excel工作薄为空!");}Sheet sheet = null;  //页数Row row = null;  //行数Cell cell = null;  //列数list = new ArrayList<List<Object>>();//遍历Excel中所有的sheetfor (int i = 0; i < work.getNumberOfSheets(); i++) {sheet = work.getSheetAt(i);if(sheet==null){continue;}//遍历当前sheet中的所有行for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {row = sheet.getRow(j);if(row==null){continue;}//遍历所有的列List<Object> li = new ArrayList<Object>();for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {cell = row.getCell(y);li.add(getValue(cell));}list.add(li);}}return list;}/*** @Description:根据文件后缀,自适应上传文件的版本* @param inStr,fileName* @return* @throws Exception*/public static  Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{Workbook wb = null;String fileType = fileName.substring(fileName.lastIndexOf("."));if(excel2003L.equals(fileType)){wb = new HSSFWorkbook(inStr);  //2003-}else if(excel2007U.equals(fileType)){wb = new XSSFWorkbook(inStr);  //2007+}else{throw new Exception("解析的文件格式有误!");}return wb;}/*** @Description:对表格中数值进行格式化* @param cell* @return*///解决excel类型问题,获得数值public static String getValue(Cell cell) {String value = "";if(null==cell){return value;}switch (cell.getCellType()) {//数值型case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {//如果是date类型则 ,获取该cell的date值Date date = DateUtil.getJavaDate(cell.getNumericCellValue());SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");value = format.format(date);;}else {// 纯数字BigDecimal big=new BigDecimal(cell.getNumericCellValue());value = big.toString();//解决1234.0  去掉后面的.0if(null!=value&&!"".equals(value.trim())){String[] item = value.split("[.]");if(1<item.length&&"0".equals(item[1])){value=item[0];}}}break;//字符串类型case STRING:value = cell.getStringCellValue();break;// 公式类型case FORMULA://读公式计算值value = String.valueOf(cell.getNumericCellValue());if (value.equals("NaN")) {// 如果获取的数据值为非法值,则转换为获取字符串value = cell.getStringCellValue();}break;// 布尔类型case BOOLEAN:value = " "+ cell.getBooleanCellValue();break;default:value = cell.getStringCellValue();}if("null".endsWith(value.trim())){value="";}return value;}}
package test.excel;import org.junit.Test;import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.List;public class TestExcel {@Testpublic void importExcel(){String filepath = "/Users/Desktop/sys_user.xlsx";FileInputStream inputStream = null;try {inputStream = new FileInputStream(new File(filepath));//把Excel文件转化成 List<List<Object>>类型的数据List<List<Object>> list = ExcelUtils.getListByExcel(inputStream, filepath);System.out.println(list);//定义第一行List<Object> firstRows = null;//数据不为空if(list != null && list.size() > 0){//拿到第一行firstRows = list.get(0);}//遍历每一行for (int i = 1; i < list.size(); i++) {//拿到这一行List<Object> rows = list.get(i);//初始化对象Demo demo = new Demo();//遍历这一行for (int j = 0; j < rows.size(); j++) {//定义cellVal,拿到每一个的值String cellVal = (String) rows.get(j);//把对象,标题名,值 都传过去TestExcel.setFieldValueByFieldName(demo, firstRows.get(j).toString().trim(), cellVal);}System.out.println(demo);}} catch (Exception e) {e.printStackTrace();}}//    @Test
//    public void testRef(){
//        tech.niua.admin.test.domain.Test test = new tech.niua.admin.test.domain.Test();
//        test.setId(100L);
//        test.setName("wangzhen");
//        Object id = TestExcel.getFieldValueByFieldName("id", test);
//        Object username = TestExcel.getFieldValueByFieldName("username", test);
//        System.out.println(username);
//    }private static void setFieldValueByFieldName(Object object, String fieldName, Object val) {try {//反射拿到所有的object的属性值Field[] fields = object.getClass().getDeclaredFields();//遍历一遍for (int i = 0; i < fields.length; i++) {//定义一个Field类型的值,遍历给它赋值Field field = fields[i];//如果传过来的fieldName等于field数据中的名称名if(fieldName.equals(field.getName())){//把它set进去field.set(object, val.toString());return;}}} catch (Exception e) {e.printStackTrace();}}private static Object getFieldValueByFieldName(String fieldName, Object object) {try {Field field = object.getClass().getField(fieldName);//设置对象的访问权限,保证对private的属性的访问return  field.get(object);} catch (Exception e) {
//            e.printStackTrace();return null;}}
}

主要步骤:

定义一个文件输入流,把excel文件放进输入流

调用ExcelUtils.getListByExcel(inputStream, filepath)  【这里把输入流和路径名当作参数,路径名当作参数是为了拿到文件名的后缀,判断xls还是xlsx,到ExcelUtils里判断版本】拿到excel文件转换成List<List<Object>>类型的数据

如果数据不为空的话,拿到数据中的第一行 list.get(0)  即标题名

for循环遍历每一行 list.get(i) ,在每一行初始化Demo对象(目的要给它赋值)

嵌套for循环遍历每一列rows.get(j),拿到每一个格的值

调用setFieldValueByFieldName方法,在一行内的每一次列遍历的时候都调用一次,而且把对应的标题名也当作参数传进去

每一行遍历结束,一个完整的Demo对象就被赋值成功了,就可以在业务中把它添加进数据库了

setFieldValueByFieldName方法

把对象,标题名,数值 传过去

通过反射拿到对象的属性值,遍历对象的属性值,如果属性名等于传过来的标题名,就可以对齐进行set,把数值set进对象里,做到了赋值 

package test.excel;import tech.niua.common.annotation.Excel;/*** Demo实体类*/
public class Demo {public String id;@Excel(name = "姓名")public String name;public String createTime;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCreateTime() {return createTime;}public void setCreateTime(String createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Demo{" +"id='" + id + '\'' +", name='" + name + '\'' +", createTime='" + createTime + '\'' +'}';}
}

 如果在实体类中添加注解

 


下面是可以实际应用的方法!!!!!!!

--改进--

因为通过上传获取服务器文件路径信息,把服务器文件路径返回到前端,再通过传递路径信息到后端对文件路径的文件进行操作

有两个缺点:

1.两次请求,慢

2.客户端可以知道服务器的路径,不安全

点击上传之间上传成功

后端接收到文件,把文件转成输入流传到getObjectList方法中,同时需要传入的还有实体类(因为需要反射获取实体类类型,在方法中给实体类List赋值),返回过来的List<Object>转换成实体类List,然后再通过mybatisplus插入进数据库

Controller层

  /*** Excel文件导入* @param file* @return* @throws Exception*/@PostMapping("/imports")@PreAuthorize("hasAuthority('/signature/imports')")//传进来二进制文件数据public ResultJson uploadFile(MultipartFile file) throws Exception {Signature signature =new Signature();List<Object> objects = ObjectList.getObjectList(file,signature);List<Signature> list =  (List<Signature>) (List)objects;boolean flag = signatureService.saveOrUpdateBatch(list);if(flag){return ResultJson.ok();}return ResultJson.failure(ResultCode.NOT_UPDATE);}

封装的文件转List<Object>方法

package tech.niua.common.excelimport;import org.springframework.web.multipart.MultipartFile;
import tech.niua.common.annotation.Excel;
import tech.niua.common.config.NiuaConfig;
import tech.niua.common.utils.file.FileUploadUtils;import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;public class ObjectList {/*** 封装的将Excel文件信息转换成List<Object>的方法,需要传实体类* @param file* @param object* @return* @throws Exception*/public static List<Object> getObjectList(MultipartFile file, Object object) throws Exception {//通过反射拿到对象Class cls = object.getClass();// 上传文件路径C:/Users/10565/Desktop/niuniu/uploadString filePath = NiuaConfig.getUploadPath();// 上传并返回新文件名称 2022/04/28/3015c5d0-8e05-4e02-b1f6-81440f373b56.xlsxString fileName = FileUploadUtils.upload(filePath, file);//完整的上传文件的路径fileName =filePath+ File.separator+fileName;//把上传的文件转换成输入流FileInputStream fileInputStream = new FileInputStream(new File(fileName));//输入流 和 文件路径  作为参数传入 获取List<List<Object>>类型数据的方法中List<List<Object>> list = ExcelUtils.getListByExcel(fileInputStream,fileName);/*** 将数据转换成List<Object>类型的数据*///初始化标题List<Object> firstRows = null;//如果转换过来的数据不为空,拿到标题if (list != null && list.size() > 0) {firstRows = list.get(0);}//初始化实际数据List<Object> excelDate = new ArrayList<>();//从一开始遍历,为的是拿到数据for (int i = 1; i < list.size(); i++) {//每一行实例化一个List<Object>数据,后面插入的也是这些List<Object> rows = list.get(i);//实例化对象,方便赋值Object obj = cls.newInstance();//对obj的每一个的字段进行赋值for (int j = 0; j < rows.size(); j++) {//把excel转过来的数据的每个字段的值转换成String类型String cellVal = (String) rows.get(j);//对obj进行赋值(实体类,字段名,字段值)ObjectList.setFieldValueByFieldName(obj, firstRows.get(j).toString().trim(), cellVal);}//添加进List<Object>,每个obj都是一条数据excelDate.add(obj);}return excelDate;}//调用一次这个方法只能给一条数据的一个字段赋值public static void setFieldValueByFieldName(Object object, String fieldName, Object val) {try {//反射拿到实体类每个变量的数据Field[] fields = object.getClass().getDeclaredFields();//把实体类每个变量遍历一遍for (int i = 0; i < fields.length; i++) {//一个实体类的一个变量,代表一种类型Field field = fields[i];field.setAccessible(true);//拿到当前实体类字段的Excel注解Excel excel = field.getAnnotation(Excel.class);if(excel==null){continue;}//如果excel转化过来的字段值和便利店实体类的遍历的注解名相同,说明对应上了,赋值!!if(fieldName.equals(excel.name())||fieldName.equals(field.getName())){//把属性值set进对象/*** 保证Integer和Long和LocalDateTime类型(实体类)也能被赋值*/if(field.getType()==Integer.class){//把有这个类型的要被赋值的对象和这个类型的数值当作参数,可以赋值field.set(object,Integer.valueOf(val.toString()));} else if(field.getType()==Long.class){field.set(object,Long.valueOf(val.toString()));}else if(field.getType()== LocalDateTime.class){DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime time = LocalDateTime.parse(val.toString(),df);field.set(object,time);}elsefield.set(object, val);return;}}} catch (Exception e) {e.printStackTrace();}}}
package tech.niua.common.excelimport;import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;/*** Created by sangyinghao* Date :2022/4/26* Description : excel导入工具类* Version :1.0*/
public class ExcelUtils {private final static String excel2003L =".xls";    //2003- 版本的excelprivate final static String excel2007U =".xlsx";   //2007+ 版本的excel/*** @Description:获取IO流中的数据,组装成List<List<Object>>对象* @param in,fileName* @return* @throws IOException*/public static List<List<Object>> getListByExcel(InputStream in, String fileName) throws Exception{List<List<Object>> list = null;//创建Excel工作薄Workbook work = getWorkbook(in,fileName);if(null == work){throw new Exception("创建Excel工作薄为空!");}Sheet sheet = null;  //页数Row row = null;  //行数Cell cell = null;  //列数list = new ArrayList<List<Object>>();//遍历Excel中所有的sheetfor (int i = 0; i < work.getNumberOfSheets(); i++) {sheet = work.getSheetAt(i);if(sheet==null){continue;}//遍历当前sheet中的所有行for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {row = sheet.getRow(j);if(row==null){continue;}//遍历所有的列List<Object> li = new ArrayList<Object>();for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {cell = row.getCell(y);li.add(getValue(cell));}list.add(li);}}return list;}/*** @Description:根据文件后缀,自适应上传文件的版本* @param inStr,fileName* @return* @throws Exception*/public static  Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{Workbook wb = null;String fileType = fileName.substring(fileName.lastIndexOf("."));if(excel2003L.equals(fileType)){wb = new HSSFWorkbook(inStr);  //2003-}else if(excel2007U.equals(fileType)){wb = new XSSFWorkbook(inStr);  //2007+}else{throw new Exception("解析的文件格式有误!");}return wb;}/*** @Description:对表格中数值进行格式化* @param cell* @return*///解决excel类型问题,获得数值public static String getValue(Cell cell) {String value = "";if(null==cell){return value;}switch (cell.getCellType()) {//数值型case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {//如果是date类型则 ,获取该cell的date值Date date = DateUtil.getJavaDate(cell.getNumericCellValue());SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");value = format.format(date);;}else {// 纯数字BigDecimal big=new BigDecimal(cell.getNumericCellValue());value = big.toString();//解决1234.0  去掉后面的.0if(null!=value&&!"".equals(value.trim())){String[] item = value.split("[.]");if(1<item.length&&"0".equals(item[1])){value=item[0];}}}break;//字符串类型case STRING:value = cell.getStringCellValue();break;// 公式类型case FORMULA://读公式计算值value = String.valueOf(cell.getNumericCellValue());if (value.equals("NaN")) {// 如果获取的数据值为非法值,则转换为获取字符串value = cell.getStringCellValue();}break;// 布尔类型case BOOLEAN:value = " "+ cell.getBooleanCellValue();break;default:value = cell.getStringCellValue();}if("null".endsWith(value.trim())){value="";}return value;}}

通用Path实体类

package tech.niua.common.domain;import lombok.Data;@Data
public class Path {private String url;private String fileName;private String path;
}

前端直接把文件传到后端 

关于文件路径部分以及上传部分

 NiuaConfig

 

 

 所以filePath是

C:/Users/10565/Desktop/niuniu/upload

 

 

 

 fileName是/年/月/日/文件名

 拼接起来就可以拿到服务器上文件路径


http://chatgpt.dhexx.cn/article/jOEHD5oT.shtml

相关文章

Java实现Excel导入导出操作详解

本文转载自 :Java实现Excel导入和导出&#xff0c;看这一篇就够了(珍藏版)_zyqok的博客-CSDN博客_excel导入 java前言最近抽了两天时间&#xff0c;把Java实现表格的相关操作进行了封装&#xff0c;本次封装是基于POI的二次开发&#xff0c;最终使用只需要调用一个工具类中的方…

EasyExcel实现excel导入

文章目录 前言一、使用步骤1.添加依赖&#xff1a;2.创建和实体类对应的用于导入导出的模板类&#xff0c;尽量不要直接使用实体类。每个字段需添加ExcelProperty注解&#xff0c;作为导入导出的识别的依据。注意value值是跟excel里的列名保持一致&#xff0c;不是跟数据库里的…

Excel表格的导入导出——EasyExcel

参考视频 csdn参考地址 一、导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version> </dependency>二、实体类 方式一&#xff1a;Excel Property&#xff08;&…

实现Excel的导入、导出

实现Excel的导入、导出 关于excel的操作在工作中经常会遇到&#xff0c;如果只是一次性使用的话&#xff0c;最简单的方式就是通过数据库的可视化工具&#xff08;如Navicat&#xff09;查询结果集之后直接一键生成excel了&#xff0c;当然这只能解燃眉之急&#xff0c;并不是…

EasyExcel复杂excel导入

EasyExcel复杂excel导入 easyexcel官方都是一些简单的导入到处示例&#xff0c;复杂的excel文档导入&#xff0c;还得自己去慢慢琢磨、百度、思考、总结、学习、观察。 代码地址在文档的最后&#xff0c;如果你也遇到这种需求&#xff0c;不妨动动你的小拇指&#xff0c;点个…

导出Excel的方式

*数据是表格的形式&#xff0c;进常用到Excel *在程序中经常可以看到有导出Excel文档&#xff0c;Excel导入数据的情况&#xff0c;现在我就说一下我学到的导出Excel *导出Excel有两种方法&#xff0c;第一种是自己设置表头的&#xff0c;第二种是填充的&#xff0c;现在我说的…

Excel文件导入导出操作

> 注意&#xff01;注意&#xff01;&#xff01;注意&#xff01;&#xff01;&#xff01; 文末有惊喜彩蛋&#xff0c;请注意查收&#xff01;日常开发工作中对于文件的相关操作大家多少都会涉及&#xff1a;上传解析、数据导出等。此篇内容主要分享一下工作中常用的Exce…

Java实现Excel导入导出

一、导入 前言&#xff1a;导入必须用post请求 具体原因在2中叙述 1、Excel导入 总结一下目标&#xff0c;就是要将excel中的数据行、逐一提取&#xff0c;最后得到一个list&#xff0c;这个list的每个元素就是excel的每个数据行的实例&#xff0c;之后的操作就是常规的jav…

Java实现Excel导入

实现前准备&#xff08;导入所需要的依赖&#xff09; <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.22</version></dependency><dependency><groupId>org.apache.…

导入Excel文件的方法

我们在做一些项目的时候通常会遇到有导入文件的这种需求&#xff0c;下面我给大家分享一下导入Excel文件的方法。 首先我们得准备一个模板&#xff0c;下图就是一个简单的EX导入模板&#xff0c; 下图就是一个导入模板&#xff0c; 我们先把导入模板写好&#xff0c; 还有一个…

两种方式导入excel

第一种 easyExcel pom文件导入 com.alibaba easyexcel 2.2.3 然后 /** * 导入用户excel * param * return */ PostMapping(“manage/imporAcc”) Message<?> imporAcc(RequestParam(“accountFile”) MultipartFile file,RequestParam(“role”)String role,Request…

Java实现Excel导入和导出,看这一篇就够了(珍藏版)

目录 目录 前言 1. 功能测试 1.1 测试准备 1.2 数据导入 1.2.1 导入解析为JSON 1.2.2 导入解析为对象&#xff08;基础&#xff09; 1.2.3 导入解析为对象&#xff08;字段自动映射&#xff09; 1.2.4 导入解析为对象&#xff08;获取行号&#xff09; 1.2.5 导入解析…

常见机器学习面试题

参考&#xff1a;http://kubicode.me/2015/08/16/Machine%20Learning/Common-Interview/?fromsinglemessage# http://blog.csdn.NET/heyongluoyao8/article/details/49429629 http://lib.csdn.Net/article/machinelearning/33798 http://www.cnblogs.com/zuochongyan/p/540705…

机器学习面试题60~100

61.说说梯度下降法 LeftNotEasy&#xff0c;本题解析来源&#xff1a;http://www.cnblogs.com/LeftNotEasy/archive/2010/12/05/mathmatic_in_machine_learning_1_regression_and_gradient_descent.html 下面是一个典型的机器学习的过程&#xff0c;首先给出一个输入数据&#…

深度学习机器学习面试题汇——模型优化,轻量化,模型压缩

深度学习机器学习面试题汇——模型优化&#xff0c;轻量化&#xff0c;模型压缩 提示&#xff1a;互联网大厂可能考的面试题 若CNN网络很庞大&#xff0c;在手机上运行效率不高&#xff0c;对应模型压缩方法有了解吗 介绍一下模型压缩常用的方法&#xff1f;为什么用知识蒸馏&…

Python干货:破解40大机器学习面试题(包含初中高级)

机器学习&#xff08;ML&#xff09;是我们世界的未来。在未来的几年中&#xff0c;几乎每种产品都将包含ML组件。ML预计将从2020年的$ 7.3B增长到2024年的$ 30.6B。对ML技能的需求遍及整个行业。 机器学习面试是一个严格的过程&#xff0c;在此过程中&#xff0c;应聘者会评估…

2021机器学习面试必考面试题汇总(附答案详解)

问题&#xff1a;Xgboost、lightGBM和Catboost之间的异同&#xff1f; 树的特征 三种算法基学习器都是决策树&#xff0c;但是树的特征以及生成的过程仍然有很多不同。 CatBoost使用对称树&#xff0c;其节点可以是镜像的。CatBoost基于的树模型其实都是完全二叉树。 XGBoo…

机器学习面试题之——简单介绍最小二乘

1、常用到的最小二乘场合&#xff1a;最小二乘法直线拟合&#xff0c;最小二乘法多项式&#xff08;曲线&#xff09;拟合&#xff0c;机器学习中线性回归的最小二乘法&#xff0c;系统辨识中的最小二乘辨识法&#xff0c;参数估计中的最小二乘法&#xff0c;等等。 2、为什么…

AI人工智能、机器学习 面试题(2022最新版)

人工智能、机器学习面试题总结&#xff0c;侧重于理解&#xff0c;回答供参考&#xff0c;欢迎讨论。 General 深度学习&#xff08;Deep Learning, DL&#xff09;和机器学习&#xff08;Machine Learning, ML&#xff09;的关系是什么&#xff1f; 深度学习是机器学习的子类…

面试官最爱用的统计学、数据科学、机器学习面试题答案

【导读】本文盘点了数据科学和机器学习面试中的常见问题&#xff0c;着眼于不同类型的面试问题。如果您计划向数据科学领域转行&#xff0c;这些问题一定会有所帮助。 技术的不断进步使得数据和信息的产生速度今非昔比&#xff0c;并且呈现出继续增长的趋势。此外&#xff0c;…