Java实现Excel导入

一、流程概念

我们需要把excel通过上传得方式导入数据库,需要以下几个步骤

  • 将excel上传到服务器指定文件内并重命名(upload)
  • 获取到文件公共路径和别名路径
  • 将上传得文件转化成输入流(poi框架)
  • 通过方法,将输入流文件数值转化成List>对象
  • 遍历excel中得值,调用一次setFieldValueByFieldName方法,就对属性赋值一次,每次循环拿到一条数据,最终得到整个数据。
  • 后台调用getObjectList(file, Exam.class)。

Java实现Excel导入_第1张图片

二、conroller中的方法

 @PostMapping("/upload")

    public ResultJson uploadFile(MultipartFile file ) throws Exception {
        List objects = ObjectList.getObjectList(file,  Exam.class);
        List list = (List) objects;
        boolean flag = examService.saveOrUpdateBatch(list);
        if (flag) {
            return ResultJson.ok();
        }
        return ResultJson.failure(ResultCode.NOT_UPDATE);
    } 
  

前天传过来得是二进制文件MultipartFile file

调用getObjectList方法(二进制文件,实体类对象)

package tech.niua.common.excelimport;

public class ObjectList {
    /**
     * 封装的将Excel文件信息转换成List的方法,需要传实体类
     * @param file
     * @param
     * @return
     * @throws Exception
     */
    public static List getObjectList(MultipartFile file, Class cls) throws Exception {
        //获取到了文件根路径
        String filePath = NiuaConfig.getUploadPath();
        // 上传并返回文件除根路径得路径 052d1c92-fc6a-4e15-a7c9-7d193c1a4bec.xlsx
        String fileName = FileUploadUtils.upload(filePath, file);
        //完整的上传文件的路径
        fileName =filePath+ File.separator+fileName;
        //把上传的文件转换成输入流(因为我们使用得是poi框架,要求使用输入流)
        FileInputStream fileInputStream = new FileInputStream(new File(fileName));
        //输入流 和 文件路径  作为参数传入 获取List>类型数据的方法中
        List> list = ExcelUtils.getListByExcel(fileInputStream,fileName);

        /**
         * 将数据转换成List类型的数据
         */
        //初始化标题
        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);
            //实例化对象,方便赋值(for里面是每次都改变数据,防止都访问这一个地址)
            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];
                ///可以访问私有
                field.setAccessible(true);
                //判断excel注解修饰
                Excel excel = field.getAnnotation(Excel.class);
                if(excel== null){
                    continue;
                }
                //如果excel转化过来的标题名和实体类字段或者实体类注解相同,说明对应上了,赋值!!
                if(fieldName.equals(excel.name())||fieldName.equals(field.getName())){
                    //将excel中得String类型得数值,转化成对应实体类属性,把属性值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);
                    }

                }

            }
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

}
 
  

package tech.niua.common.excelimport;



/**
 * Created by ws
 * Date :2022/4/29
 * Description : excel导入工具类
 * Version :1.0
 */
public class ExcelUtils {

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

    /**
     * @Description:获取IO流中的数据,组装成List>对象
     * @param in,fileName
     * @return
     * @throws IOException
     */
    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
            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;

    }

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

 三、导入成功

Java实现Excel导入_第2张图片

Java实现Excel导入_第3张图片

你可能感兴趣的:(Java基础,java,开发语言)