基于poi 3.17导入excel文件 含处理字典项转换为状态

excel 文件下拉框字典项

要转换为数据库状态

fault_code为字符串类型

一般通过后端处理

写一个监听器类,处理从流中得到的数据

有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去

java 复制代码
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.wedu.modules.app.entity.UserEntity;
import com.wedu.modules.fault.entity.Register;
import com.wedu.modules.fault.mapper.RegisterMapper;
import com.wedu.modules.fault.service.IRegisterService;
import com.wedu.modules.sys.entity.SysDictEntity;
import com.wedu.modules.sys.entity.SysUserEntity;
import com.wedu.modules.sys.service.SysDictService;
import com.wedu.modules.sys.service.SysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.wedu.modules.fault.util.TimeConversionStringUtil.*;
import static com.wedu.common.utils.ShiroUtils.getUserId;

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class UploadDataListener extends AnalysisEventListener<Register> {
    private static final Logger LOGGER = LoggerFactory.getLogger(UploadDataListener.class);
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<Register> list = new ArrayList<>();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private IRegisterService registerService;

    private SysUserService userService;

    private SysDictService dictService;


//    public UploadDataListener() {
//        // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
//        demoDAO = new DemoDAO();
//    }

    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param registerService
     */
    public UploadDataListener(IRegisterService registerService,SysUserService userService, SysDictService dictService) {
        this.registerService = registerService;
        this.userService = userService;
        this.dictService = dictService;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link }
     * @param context
     */
    @Override
    public void invoke(Register data, AnalysisContext context) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        LOGGER.info("{}条数据,开始存储数据库!", list.size());
//        List<SysUserEntity> userEntityList = new ArrayList<>();
        // 获取字典字符列表
        List<SysDictEntity> dictEntities = dictService.maintenanceList("faultCode");
        for (Register register : list) {
            //处理时间字符串为时间戳
            long redTime = convertToMilliseconds(register.getRedTimeChar());
            register.setRedTime(redTime);
            long repTime = convertToMilliseconds(register.getRepTimeChar());
            register.setRepTime(repTime);
            register.setCreateTime(new Date());
            register.setCreateBy(getUserId());

            // 遍历字典和实体类进行比对然后重新赋值
            for (SysDictEntity dictEntity : dictEntities) {
                if (dictEntity.getName().equals(register.getFaultCode())) {
                    register.setFaultCode(dictEntity.getValue());
                }
            }
            // 为了关联表的插入,模拟实现插入用户
//            // 检查用户名是否已存在
//            boolean usernameExists = userService.checkUsernameExists(register.getSysUsername());
//
//            if (!usernameExists) {
//                SysUserEntity user = new SysUserEntity();
//                // 取出user表必要信息,设置信息必要的属性
//                user.setUsername(register.getSysUsername());
//                user.setMobile(register.getPhone());
//                user.setPassword("123");
//                user.setStatus(1);
//                user.setCreateUserId(getUserId());
//                userService.saveUser(user);
                userEntityList.add(user);
//            }
        }

        // 执行sql
        // 执行用户信息批量插入
//        if (!userEntityList.isEmpty()) {
//            userService.saveBatch(userEntityList);
//        }
        registerService.saveBatch(list);
        LOGGER.info("存储数据库成功!");
    }
}

controller层访问接口

java 复制代码
    /**
     * easy excel上传
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/importEasyExcel")
    public R importEasyExcel(MultipartFile file) throws Exception {
        // 测试获取数据
//        String fileName = "C:\\Users\\HP\\Desktop\\ey导出.xlsx";
//        List<Register> list = EasyExcel.read(fileName).head(Register.class).sheet().doReadSync();
//        for (Register data : list) {
//            System.out.println("读取到数据:{}" + JSON.toJSONString(data));
//        }
        EasyExcel.read(file.getInputStream(), Register.class, new UploadDataListener(registerService, userService, dictService)).sheet().doRead();
        return R.ok();
    }

前端:使用element组件的上传方法

使用异步Ajax方法

按钮绑定方法

java 复制代码
      <el-form-item>
        <el-upload
          class="upload-demo"
          action="#"
          :on-change="handleChange"
          :on-exceed="handleExceed"
          :file-list="fileList"
          :limit="1"
          multiple
          :auto-upload="true"
        >
          <el-button
            size="small"
            round
            type="primary"
          >点击上传</el-button>
        </el-upload>
      </el-form-item>

methods方法

javascript 复制代码
// 导入excel
    // 文件超出个数提示
    handleExceed (files, fileList) {
      this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
    },
    handleChange (file) {
      let formData = new FormData()
      formData.append('file', file.raw) // 传文件
      this.$http({
        url: this.$http.adornUrl('/register/importEasyExcel'),
        method: 'post',
        data: formData,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.$message({
            message: '操作成功',
            type: 'success',
            duration: 1500
          })
          this.getDataList()
          this.$refs.upload.clearFiles() // 清除文件
        } else {
          this.$message.error(data.msg)
        }
      })
    },
相关推荐
弗拉唐6 小时前
将Excel文件的两个表格经过验证后分别读取到Excel表和数据库
数据库·excel
Lizzy_Fly6 小时前
【Excel】身份证号最后一位“X”怎么计算
excel
深情废杨杨6 小时前
后端-实现excel的导出功能(超详细讲解)
java·spring boot·excel
智汇探长6 小时前
EasyExcel自定义设置Excel表格宽高
java·excel·easyexcel
Eiceblue6 小时前
通过Python 调整Excel行高、列宽
开发语言·vscode·python·pycharm·excel
crackbuy6 小时前
Excel筛选的操作教程
excel
笔墨登场说说7 小时前
Excel SUMIFS
excel
Lizzy_Fly8 小时前
【Excel】ToRow超级查找函数
excel
mon_star°9 小时前
将答题成绩排行榜数据通过前端生成excel的方式实现导出下载功能
前端·excel
冰淇淋烤布蕾17 小时前
EasyExcel使用
java·开发语言·excel