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

Posted C'z x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将Excel表中数据导入数据库(看了就会)相关的知识,希望对你有一定的参考价值。

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

首先我用的是框架

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

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

将Excel表中数据导入数据库

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

NiuaConfig.getUploadPath()方法--通过注解获取yml中定义的服务器文件上传路径

 FileUploadUtils.upload方法

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

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

File desc = getAbsoluteFile(baseDir, fileName)将文件路径完整拼接没有那层他都会自己创建

 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注解中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表中 在线等·

想把北京福彩快乐8的中将数据导入到excel中,网页有2000多页,不知怎么弄,简单的数据导入不行,希望哪位大拿帮忙弄一个每6分钟刷新一次的excel表格。网址如下:
http://www.bwlc.net/bulletin/search.jsp?id=3&period=&year=&month=&day=&page=1

正常的途径有2种:
1.找网站的系统管理员;(缺点:把握性不大;)
2.自己复制就可以了;(缺点:麻烦!)
非正常的途径:
找人把网站黑了,从后台把数据库拿下来就可以了!(缺点:违法!)
综合以上:
孰重孰轻,慎重选择!
参考技术A 同问,求解。。。 参考技术B 你是说自动导入随着网页一起更新吗

以上是关于将Excel表中数据导入数据库(看了就会)的主要内容,如果未能解决你的问题,请参考以下文章

java怎么将excel中string类型在导入到数据库时转换成表中对应的id

怎样将MySQL数据导出到Excel表中

java中怎么让导入的excle表中每一条数据对应文件夹中对应的图片

怎样将MySQL数据导出到Excel表中

如何用Java实现把excel表中的数据导入到mysql数据库已有的表中?

用JAVA快速的将一个表中的数据导入到另一个表里