Vue + ElementPlus 实现权限管理系统(十): 实现用户管理Excel的导入导出功能

文接上回,上篇文章我们已经使用NestJS实现了后端部分的 excel 的导入和导出功能。本篇文章我们将介绍根据后端提供的接口如何在前端实现 excel 的导入和导出功能。实现效果如下图所示

点击导出按钮,可以根据我们的选择条件下载对应的 excel 文件。点击导入按钮,可以点击或拖拽上传对应的 excel 文件,并导入到数据库中。

导出 Excel

因为我们要导出文件,所以需要下载后台返回的二进制(blob)文件,这样一来我们通用的接口调用封装就不再适用了。所以我们需要在封装 axios 的文件utils/http/index.ts中新增一个通用的下载方法downLoad。并且安装file-saver,使用它的saveAs方法来下载文件。

js 复制代码
import { saveAs } from "file-saver";
//....
//下载
export const downLoad = async (url: string, params: any, filename: string) => {
  const res = await service({
    url,
    method: "get",
    params: params,
    responseType: "blob",
  });

  const blob = new Blob([res]);
  saveAs(blob, `${filename}.xlsx`);
};

然后再user/index.vue中新增导入按钮并设置其权限再调用下载方法并传入参数即可。

js 复制代码
<el-col :span="1.5">
        <el-button
          type="warning"
          v-hasPerm="['system:user:export']"
          plain
          icon="Download"
          @click="exportDataList()"
          >导出</el-button>
</el-col>
...
//导出
const exportDataList = async () => {
  downLoad("/user/export", queryParams, `用户列表_${new Date().getTime()}`);
};

这样我们点击导出按钮就可以下载对应的 excel 文件了。

导入 Excel

当用户点击导入按钮后,我们需要弹窗让用户选择文件或拖拽文件,然后上传到后台。这里我们可以使用element-plusupload组件来实现。

js 复制代码
<el-dialog
      width="400px"
      :title="uploadParams.title"
      v-model="uploadParams.open"
      append-to-body
    >
      <el-upload
        class="upload-demo"
        drag
        accept=".xlsx, .xls"
        :limit="1"
        ref="upload"
        :auto-upload="false"
        :action="uploadParams.url"
        :headers="uploadParams.headers"
        :on-exceed="handleExceed"
        :disabled="uploadParams.isUploading"
        :on-progress="handleProgress"
        :on-success="handleFileSuccess"
      >
        <el-icon class="el-icon--upload">
          <component is="UploadFilled" />
        </el-icon>
        <div class="el-upload__text">拖拽文件到这或 <em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip">仅允许导入xls、xlsx格式文件。</div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="uploadSubmit">确 定</el-button>
          <el-button @click="uploadParams.open = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>

其中 action 是我们后台的请求地址,headers 是我们的请求头,auto-upload 是是否自动上传,disabled 是是否禁用,limit 是上传文件的数量。on-exceed 是超出限制时的回调函数,on-progress 是上传进度的回调函数,on-success 是上传成功的回调函数。

然后定义一下 uploadParams,处理一下相关逻辑

js 复制代码
/*** 用户导入参数 */
const uploadParams = reactive({
  // 是否显示弹出层(用户导入)
  open: false,
  // 弹出层标题(用户导入)
  title: "",
  // 上传中
  isUploading: false,
  // 设置上传的请求头部带上token
  headers: { Authorization: "Bearer " + Storage.get("token") },
  // 上传的地址
  url: import.meta.env.VITE_APP_API + "/user/upload",
});
const importDataList = async () => {
  uploadParams.open = true;
  uploadParams.title = "用户导入";
};
const upload = ref<UploadInstance>();

// 文件选择覆盖前一个文件
const handleExceed: UploadProps["onExceed"] = (files) => {
  upload.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  upload.value!.handleStart(file);
};

//上传中
const handleProgress: UploadProps["onProgress"] = () => {
  uploadParams.isUploading = true;
};

// 上传提交
const uploadSubmit = () => {
  upload.value!.submit();
};
// 上传成功处理
const handleFileSuccess: UploadProps["onSuccess"] = (response) => {
  upload.value!.clearFiles();
  uploadParams.isUploading = false;
  const { code, describe } = response;
  if (code !== 200) {
    ElMessage.error(describe);
    return;
  }
  ElMessage.success("导入成功");
  uploadParams.open = false;
  getList();
};

此时我们就可以进行文件导入了

我们导入两个用户试一下。

导入成功之后可以看到列表中已经有了我们导入的两个用户。

到这里就实现了 excel 的导入和导出功能。其它模块的导入导出基本和用户模块的导入导出一致,这里就不再一一介绍了。

源码地址

相关推荐
Suppose1 小时前
[Vue]template相关
vue.js
cnsxjean2 小时前
Vue教程|搭建vue项目|Vue-CLI2.x 模板脚手架
javascript·vue.js·ui·前端框架·npm
web组态软件2 小时前
BY组态-低代码web可视化组件
前端·低代码
react_in2 小时前
webpack 题目
前端·webpack
MarisolHu2 小时前
前端学习笔记-Vue篇-02
前端·vue.js·笔记·学习
学前端的小朱2 小时前
Webpack的基础配置
前端·webpack·node.js
小小优化师 anny3 小时前
JS +CSS @keyframes fadeInUp 来定义载入动画
javascript·css·css3
小周同学_丶3 小时前
解决el-select数据量过大的3种方法
前端·vue.js·elementui
先知demons4 小时前
uniapp开发微信小程序笔记10-触底加载
前端·笔记·微信小程序·小程序·uni-app
每一天,每一步4 小时前
react antd不在form表单中提交表单数据,而是点查询按钮时才将form表单数据和其他查询条件一起触发一次查询,避免重复触发请求
前端·javascript·react.js