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();
    }
相关推荐
m0_748248772 小时前
【前端 Uniapp】使用Vant打造Uniapp项目(避坑版)
前端·uni-app
深海的鲸同学 luvi2 小时前
高德地图离线加载解决方案(内网部署)+本地地图瓦片加载
前端·javascript·html5
码字哥3 小时前
EasyExcel设置表头上面的那种大标题(前端传递来的大标题)
java·服务器·前端
凌盛羽3 小时前
C#对Excel表csv文件的读写操作
开发语言·windows·物联网·microsoft·c#·excel
途途途途4 小时前
Python 给 Excel 写入数据的四种方法
windows·python·excel
grace_jm20084 小时前
Excel VBA语句集
excel
GIS好难学5 小时前
《Vue进阶教程》第六课:computed()函数详解(上)
前端·javascript·vue.js
nyf_unknown5 小时前
(css)element中el-select下拉框整体样式修改
前端·css
m0_548514775 小时前
前端打印功能(vue +springboot)
前端·vue.js·spring boot
执键行天涯5 小时前
element-plus中的resetFields()方法
前端·javascript·vue.js