将Excel表中数据导入数据库(看了就会)

2年前 (2022) 程序员胖胖胖虎阿
387 0 0

一些用户要求Excel导入学生信息或试题信息这就用到了Excel导入功能,下面我们具体讲讲Excel如何导入

首先我用的是框架

niua: 基于Springboot的后台管理系统 - Gitee.com

此框架还有自动生成增删改查和前端vue页面

将Excel表中数据导入数据库

第一步,我们要将本地Excel表上传到服务器(此次我就将我的本地电脑当做了服务器),并返回服务中Excel表的名称,拼接服务器中Excel表的绝对路径。

将Excel表中数据导入数据库(看了就会)NiuaConfig.getUploadPath()方法--通过注解获取yml中定义的服务器文件上传路径

将Excel表中数据导入数据库(看了就会)

将Excel表中数据导入数据库(看了就会)

将Excel表中数据导入数据库(看了就会)

 FileUploadUtils.upload方法

将Excel表中数据导入数据库(看了就会)

将Excel表中数据导入数据库(看了就会)

 extractFilename(file)方法--传入二进制文件

将Excel表中数据导入数据库(看了就会)

 在文件存储路径创建文件夹以便于管理、例如

将Excel表中数据导入数据库(看了就会)File desc = getAbsoluteFile(baseDir, fileName)将文件路径完整拼接没有那层他都会自己创建

将Excel表中数据导入数据库(看了就会)

 file.transferTo(desc)将二进制文件写入指定文件夹

到这文件上传就完成了。返回文件路径,就可以引用了。

upload是方法拼接的 

//上传文件路径 F:\\Program Files\\java\\chaozexu\\bdks\\demo\\upload\\
String filePath = NiuaConfig.getUploadPath();
//上传文件并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
//拼接文件上传到服务器的绝对路径
fileName = filePath + File.separator + fileName;

第二步,解析我们Excel表中数据,并将Excel中的数据和java的属性进行匹配或赋值

Excel表数据

将Excel表中数据导入数据库(看了就会)

 Excel表头数据要和实体类中Excel注解中name对应

public class Exam {

        @TableId(type = IdType.AUTO)
        @Excel(name = "序号", cellType = Excel.ColumnType.NUMERIC)
        private Long id;

        @Excel(name = "考试名称")
        private String name;

        @Excel(name = "考试时间")
        private LocalDateTime examTime;

        @Excel(name = "考试描述")
        private String description;

        @ApiModelProperty(value = "更新时间")
        @TableField(fill = FieldFill.INSERT_UPDATE)
        @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime updateTime;

        @ApiModelProperty(value = "创建时间")
        @TableField(fill = FieldFill.INSERT)
        @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;

        @TableField(exist=false)
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeBegin;
        @TableField(exist=false)
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeEnd;


        @Excel(name = "删除标识0正常")
        private Integer deleteFlag;





}
package tech.niua.admin.util;

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;

/**
 * 解析我们Excel表中数据,并将Excel中的数据和java的属性进行匹配或赋值
 */
public class ExcelImport {
    //返回List<Object>类型的数据
    /**
     * 
     * @param file  二进制文件
     * @param object  实体类
     * @return
     * @throws Exception
     */
    public static List<Object> importExcel(MultipartFile file, Class cls) throws Exception {
        //上传文件路径 F:\\Program Files\\java\\chaozexu\\bdks\\demo\\upload\\
        String filePath = NiuaConfig.getUploadPath();
        //上传文件并返回新文件名称
        String 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);
        }
        //创建excelDate集合,将需要插入数据库的数据放到excelDate中
        List<Object> excelDate = new ArrayList<>();
        //遍历每行数据
        for (int i = 1; i < list.size(); i++) {
            List<Object> rows = list.get(i);
            //通过反射实例化处理的类
            Object obj = cls.newInstance();
            //对每行的每列进行遍历
            for (int j = 0; j < rows.size(); j++) {
                String cellVal = (String) rows.get(j);
                //调用方法给实体类属性赋值
                ExcelImport.setFieldValueByFieldName(obj, firstRows.get(j).toString().trim(), cellVal);
            }
            excelDate.add(obj);
        }
        return excelDate;
    }


    /**
     * 通过反射判断注解和属性名并给实体类赋值
     * 将获取的数据的数据类型,转化为实体类属性类型
     * @param object
     * @param fieldName
     * @param val
     */
    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;
                }
                if(fieldName.equals(excel.name())||fieldName.equals(field.getName())){
                    //把属性值set进对象
                    //将String类型强转换为其实体类相对应的类型
                    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 LocalTime = LocalDateTime.parse( val.toString(),df);
                        field.set(object,LocalTime);
                    }else
                        field.set(object, val);
                    return;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}

Excel工具类(将Excel表中数据转成List<List<Object>>形式)

package tech.niua.admin.util;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

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;

/**
 * Created by Guanzhong Hu
 * Date :2020/2/12
 * 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<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中所有的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<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  去掉后面的.0
                    if(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;
    }


}

第三步,批量插入到我们的数据库

    /**
     * 数据导入
     * @return
     */
    @PreAuthorize("hasAuthority('/exam/dataImport')")
    @PostMapping("/dataImport")
    public ResultJson uploadFile(MultipartFile file) throws Exception {
        List<Object> objects = ExcelImport.importExcel(file,Exam.class);
        List<Exam> list = (List)objects;
        boolean flag = examService.saveOrUpdateBatch(list);
        if(flag){
            return ResultJson.ok();
        }
        return ResultJson.failure(ResultCode.NOT_UPDATE);
    }

vue上传功能 

<template>
    <div class="component-upload-image">
        <el-upload
                drag
                :action="uploadImgUrl"
                :on-success="handleUploadSuccess"
                :before-upload="handleBeforeUpload"
                :on-error="handleUploadError"
                name="file"
                :show-file-list="false"
                :headers="headers"
        >
             <i class="el-icon-upload"></i>
             <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        </el-upload>
        <el-row>
            <span>
                {{uploadUrlPath}}
            </span>

        </el-row>
    </div>
</template>

<script>
    import { getToken } from '@/utils/auth';

    export default {
        components: {},
        data() {
            return {
                uploadImgUrl:  "/v1/exam/dataImport", // 上传的图片服务器地址
                headers: {
                    Authorization: "Bearer " + getToken(),
                },
                uploadUrlPath: "没有文件上传",
            };
        },
        props: {
            value: {
                type: String,
                default: "",
            },
        },
        methods: {
            handleUploadSuccess(res) {
                this.uploadUrlPath = JSON.stringify(res);
                this.loading.close();
            },
            handleBeforeUpload() {
                this.loading = this.$loading({
                    lock: true,
                    text: "上传中",
                    background: "rgba(0, 0, 0, 0.7)",
                });
            },
            handleUploadError() {
                this.$message({
                    type: "error",
                    message: "上传失败",
                });
                this.loading.close();
            },
        },
        watch: {},
    };
</script>

<style scoped lang="scss">
    .avatar {
        width: 100%;
        height: 100%;
    }
</style>

将Excel表中数据导入数据库(看了就会)

 结果展示

将Excel表中数据导入数据库(看了就会)

版权声明:程序员胖胖胖虎阿 发表于 2022年10月4日 上午9:56。
转载请注明:将Excel表中数据导入数据库(看了就会) | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...