目录

ruoyi的excel批量导入

最简单方式

若依的官方文档提供了教程,可以按照起前后端的教学,进行代码编写

前段

组件

html 复制代码
    <!-- 导入对话框 -->
    <el-dialog
        title="导入数据"
        v-model="openImport"
        width="500px"
        append-to-body
    >
      <el-upload
          ref="uploadRef"
          class="upload-demo"
          :action="uploadFileUrl"
          accept=".xlsx, .xls"
          :headers="headers"
          :limit="1"
          :auto-upload="false"
          :on-success="uploadSuccess"
          :on-error="uploadError"
          :before-upload="beforeUpload"
      >
        <template #trigger>
          <el-button type="primary">选择文件</el-button>
        </template>

        <el-button class="ml-3" type="success" @click="submitUpload" style="margin-left: 20px">
          上传文件
        </el-button>

        <template #tip>
          <div class="el-upload__tip">
            请上传Excel文件,<el-link type="primary">点击下载模板</el-link>
          </div>
        </template>
      </el-upload>

    </el-dialog>

上传文件:有heads,上传的url必须是动态拼接

js 复制代码
/** 导入文件 */
const uploadRef = ref({});
const headers = ref({Authorization: "Bearer " + getToken()}); // 请求头
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/manage/sku/import"); // 上传文件服务器地址
function submitUpload() {
  uploadRef.value.submit();
}

仿照若依的imageload改造,可以对上传的文件进行简单的校验

js 复制代码
/** 上传前校检格式和大小 */
const props = defineProps({
  modelValue: [String, Object, Array],
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 1,
  },
  // 文件类型, 例如['xlsx', 'xls']
  fileType: {
    type: Array,
    default: () => ["xlsx", "xls"],
  },
});
function beforeUpload(file) {
  let isExcel = false;
  if (props.fileType.length) {
    let fileExtension = "";
    if (file.name.lastIndexOf(".") > -1) {
      fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
    }
    isExcel = props.fileType.some(type => {
      if (file.type.indexOf(type) > -1) return true;
      if (fileExtension && fileExtension.indexOf(type) > -1) return true;
      return false;
    });
  }

成功回调函数和失败回调函数

js 复制代码
/** 上传成功 */
function uploadSuccess(response, file, fileList) {
  if (response.code === 200) {
    proxy.$modal.msgSuccess("上传成功");
    openImport.value = false;
    getList();
  } else {
    proxy.$modal.msgError(response.msg);
  }
  // 上传成功后清空文件列表
  uploadRef.value.clearFiles();
  // 关闭提示信息
  proxy.$modal.closeLoading();
}

/** 上传失败 */
function uploadError(err) {
  proxy.$modal.msgError("上传失败");
  // 上传失败后清空文件列表
  uploadRef.value.clearFiles();
  // 关闭提示信息
  proxy.$modal.closeLoading();
}

controller层

java 复制代码
    /**
     * 商品导入
     */
    @PreAuthorize("@ss.hasPermi('manage:sku:import')")
    @Log(title = "商品管理", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<Sku> util = new ExcelUtil<Sku>(Sku.class);
        List<Sku> skuList = util.importExcel(file.getInputStream());
        String operName = SecurityUtils.getUsername();
        updateSupport = true;
        String message = skuService.importSkuList(skuList, updateSupport, operName);
        return AjaxResult.success(message);

    }

service层

java 复制代码
    /**
     * 导入商品数据
     *
     * @param skuList 商品数据列表
     * @param updateSupport 是否更新支持,如果已存在,则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importSkuList(List<Sku> skuList, boolean updateSupport, String operName) {
        if (CollUtil.isEmpty(skuList)) {
            throw new RuntimeException("导入数据不能为空!");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (Sku sku : skuList) {
            try {
                // 验证是否存在这个商品
                Sku queryEntity = new Sku();
                queryEntity.setSkuName(sku.getSkuName());
                List<Sku> existingSkuList = skuMapper.selectSkuList(queryEntity);

                Optional<List<Sku>> optionalSkuList = Optional.ofNullable(existingSkuList);
                if (optionalSkuList.isPresent() && !optionalSkuList.get().isEmpty()) {
                    if (!updateSupport) {
                        failureNum++;
                        failureMsg.append("<br/>").append(failureNum).append("、商品名称 ").append(sku.getSkuName()).append(" 已存在");
                        continue;
                    } else {
                        sku.setUpdateBy(operName);
                        // 根据名称获取skuId
                        sku.setSkuId(existingSkuList.get(0).getSkuId());
                        // 更新sku
                        skuMapper.updateSku(sku);
                    }
                } else {
                    sku.setCreateBy(operName);
                    sku.setUpdateBy(operName);
                    skuMapper.insertSku(sku);
                }
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、商品名称 ").append(sku.getSkuName()).append(" 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、商品名称 " + sku.getSkuName() + " 导入失败:";
                failureMsg.append(msg).append(e.getMessage());
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
            throw new RuntimeException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您,数据已全部导入成功!");
            if (successNum == 0) {
                successMsg.append("0条数据导入成功,数据已存在");
            }
        }
        return successMsg.toString();
    }
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
vvilkim1 小时前
深入理解 TypeScript 中的 implements 和 extends:区别与应用场景
前端·javascript·typescript
GISer_Jing1 小时前
前端算法实战:大小堆原理与应用详解(React中优先队列实现|求前K个最大数/高频元素)
前端·算法·react.js
写代码的小王吧3 小时前
【安全】Web渗透测试(全流程)_渗透测试学习流程图
linux·前端·网络·学习·安全·网络安全·ssh
小小小小宇3 小时前
CSS 渐变色
前端
PacosonSWJTU4 小时前
python基础-13-处理excel电子表格
开发语言·python·excel
snow@li4 小时前
前端:开源软件镜像站 / 清华大学开源软件镜像站 / 阿里云 / 网易 / 搜狐
前端·开源软件镜像站
小小小小宇4 小时前
配置 Gemini Code Assist 插件
前端
one 大白(●—●)4 小时前
前端用用jsonp的方式解决跨域问题
前端·jsonp跨域
刺客-Andy4 小时前
前端加密方式 AES对称加密 RSA非对称加密 以及 MD5哈希算法详解
前端·javascript·算法·哈希算法
记得早睡~4 小时前
leetcode122-买卖股票的最佳时机II
javascript·数据结构·算法·leetcode