栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

excel导入功能

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

excel导入功能

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

需要用到ExcelUtils工具类

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

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;


public class ExcelUtils {

    private final static String excel2003L =".xls";    //2003- 版本的excel
    private final static String excel2007U =".xlsx";   //2007+ 版本的excel

    
    public static List> getListByExcel(InputStream in, String fileName) throws Exception{
        List> 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>();
        //遍历Excel中所有的sheet
        for (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 li = new ArrayList();
                for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                    cell = row.getCell(y);
                    li.add(getValue(cell));
                }
                list.add(li);
            }
        }

        return list;

    }

    
    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;
    }

    
    //解决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  去掉后面的.0
                    if(null!=value&&!"".equals(value.trim())){
                        String[] item = value.split("[.]");
                        if(1 
 
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 {

    @Test
    public void importExcel(){

        String filepath = "/Users/Desktop/sys_user.xlsx";
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(new File(filepath));
            //把Excel文件转化成 List>类型的数据
            List> list = ExcelUtils.getListByExcel(inputStream, filepath);
            System.out.println(list);
            //定义第一行
            List firstRows = null;
            //数据不为空
            if(list != null && list.size() > 0){
                //拿到第一行
                firstRows = list.get(0);
            }
            //遍历每一行
            for (int i = 1; i < list.size(); i++) {
                //拿到这一行
                List 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.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;


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;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "id='" + id + ''' +
                ", name='" + name + ''' +
                ", createTime='" + createTime + ''' +
                '}';
    }
}

 如果在实体类中添加注解

 


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

--改进--

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

有两个缺点:

1.两次请求,慢

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

点击上传之间上传成功

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

Controller层

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

    } 
 

封装的文件转List方法

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 {
    
    public static List getObjectList(MultipartFile file, Object object) throws Exception {
        //通过反射拿到对象
        Class cls = object.getClass();
        // 上传文件路径C:/Users/10565/Desktop/niuniu/upload
        String filePath = NiuaConfig.getUploadPath();
        // 上传并返回新文件名称 2022/04/28/3015c5d0-8e05-4e02-b1f6-81440f373b56.xlsx
        String fileName = FileUploadUtils.upload(filePath, file);
        //完整的上传文件的路径
        fileName =filePath+ File.separator+fileName;
        //把上传的文件转换成输入流
        FileInputStream fileInputStream = new FileInputStream(new File(fileName));
        //输入流 和 文件路径  作为参数传入 获取List>类型数据的方法中
        List> list = ExcelUtils.getListByExcel(fileInputStream,fileName);
        
        //初始化标题
        List firstRows = null;
        //如果转换过来的数据不为空,拿到标题
        if (list != null && list.size() > 0) {
            firstRows = list.get(0);
        }
        //初始化实际数据
        List excelDate = new ArrayList<>();
        //从一开始遍历,为的是拿到数据
        for (int i = 1; i < list.size(); i++) {
            //每一行实例化一个List数据,后面插入的也是这些
            List 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,每个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];
                //拿到当前实体类字段的Excel注解
                Excel excel = field.getAnnotation(Excel.class);
                if(excel==null){
                    continue;
                }
                //如果excel转化过来的字段值和便利店实体类的遍历的注解名相同,说明对应上了,赋值!!
                if(fieldName.equals(excel.name())||fieldName.equals(field.getName())){
                    //把属性值set进对象
                    
                    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);
                    }
                    else
                        field.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;


public class ExcelUtils {

    private final static String excel2003L =".xls";    //2003- 版本的excel
    private final static String excel2007U =".xlsx";   //2007+ 版本的excel

    
    public static List> getListByExcel(InputStream in, String fileName) throws Exception{
        List> 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>();
        //遍历Excel中所有的sheet
        for (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 li = new ArrayList();
                for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                    cell = row.getCell(y);
                    li.add(getValue(cell));
                }
                list.add(li);
            }
        }

        return list;

    }

    
    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;
    }

    
    //解决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  去掉后面的.0
                    if(null!=value&&!"".equals(value.trim())){
                        String[] item = value.split("[.]");
                        if(1 
 

通用Path实体类

package tech.niua.common.domain;

import lombok.Data;

@Data
public class Path {
    private String url;
    private String fileName;
    private String path;
}

前端直接把文件传到后端 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号