upload 文件自动上传写法,前后端 下载流文件流

news2025/1/18 6:19:48
<el-upload
          v-model:file-list="fileList"
          :action="app.api+'/student/student/import'"
          :headers="{
       //   'Content-Type': 'multipart/form-data;boundary=----split-boundary', 此处切记不要加,否则会造成后端报错  Required request part 'file' is not present 
          'token':token
          }"
          name="file"//此处默认为file
          class="upload-demo"
          @on-success="handleSuccess"
          :on-error="handleAvatarSuccess"
          :limit="3"
          :on-progress="beforeAvatarUpload"
        >
<!--:auto-upload="false"-->
          <!--          :http-request="replaceRes"-->
          <span v-if="jinDu">
            <el-progress style="width: 245px; height: 19px" :text-inside="true" :stroke-width="20"
                         :percentage="percentage"/>
          </span>
          <span v-if="isUpload" style="color: #59c2c7;cursor:pointer;"
                @click="uploadChangeValue">导入学生学籍信息</span>
          <template #tip>
            <span style="color: #ff8282; margin-left: 20px">{{ importText }}</span>
          </template>
        </el-upload>
<script lang="ts" setup>

//此处后端穿了一个流给前端,所以需要解析一下,然后赋值给一个按钮,在点击时候才下载!!!
const handleSuccess = (response: any) => {
  console.log(response)
  if (Object.values(response.headers)[0] == 'application/vnd.ms-excel;charset=UTF-8') {
    const url = window.URL.createObjectURL(new Blob([response.data]));
    // 创建a标签,并隐藏a标签
    let link = document.createElement('a')
    link.style.display = 'none'
    // a标签的href属性指定下载链接
    link.href = url
    //setAttribute() 方法添加指定的属性,并为其赋指定的值
    // 后缀格式.csv/.xsls要和需要和后端返回格式相同,这里以.csv为例
    link.setAttribute('download', '文件名称.xlsx')
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
};


//此处用于实时监听进度条进度
const beforeAvatarUpload = (event: any) => {
  let loadProgress = Math.floor(event.percent); //这就是当前上传的进度
  //可以进行其他逻辑
  percentage.value = loadProgress;
  importText.value = "学籍信息导入中……";
  if (percentage.value == 100) {
    importText.value = "学籍导入成功!"
  }
};
</script>
    @PostMapping("import")
    @ApiOperation("导入")
    @RequiresPermissions("student:student:import")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "file")
    public void importExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception {
        UserDetail userDetail = SecurityUser.getUser();
        //保存所有的表单信息、如果表达有错误、将返回给客户端
        if (userWithErrorListInMap == null) {
            userWithErrorListInMap = new HashMap<>();
        }
        //每次都清空数据
        userWithErrorListInMap.put(userDetail.getId(), new ArrayList<>());

        ZsRef<Boolean> hasError = new ZsRef<>();
        new ExcelServiceListener<StudentExcel, StudentEntity>(studentService, file.getInputStream()) {
            private List<RegionEntity> regionList;

            /**
             * 地区编码 去掉末尾的数字0, 用于判断权限
             */
            private String userRegionCodeForPermission;

            private SchoolEntity schoolForPermission;

            @Override
            public void invoke(StudentExcel data, AnalysisContext context) {

                if (regionList == null) {
                    regionList = regionService.selectList(new HashMap<>());
                }
                if (userDetail.getRegionCode() != null) {
                    //去掉地区编码后面的0
                    userRegionCodeForPermission = userDetail.getRegionCode().replaceAll("0+?$", "");
                }

                if (userDetail.getSchoolCode() != null) {
                    schoolForPermission = schoolService.selectByParams("schoolCode", userDetail.getSchoolCode());
                }
                // 校验姓名
                if (data.getName() == null) {
                    hasError.value = true;
                    data.setName(data.getName() + "##名字不能为空, 长度最多四汉字");
                }
                // 校验性别
                if (data.getGender() == 2) {
                    hasError.value = true;
                    data.setGenderStr(data.getGenderStr() + "##性别只能是(男、女)中的一个");
                }

                // 校验身份证号
                if (isEmpty(data.getIdCard()) || data.getIdCard().length() != 18) {
                    hasError.value = true;
                    data.setName(data.getName() + "##身份证长度18位");
                }

                if (isEmpty(data.getNation())) {
                    hasError.value = true;
                    data.setNation(data.getNation() + "##民族不能为空");
                }

                // ************************ 校验地区 *********************************
                // 判断地区表中是否包含含这一项
                RegionEntity region1 = null, region2 = null;
                for (RegionEntity item : regionList) {
                    if (data.getRegion1() != null && data.getRegion1().contains(item.getName())) {
                        region1 = item;
                    }
                    if (data.getRegion2() != null && data.getRegion2().contains(item.getName())) {
                        region2 = item;
                    }
                }
                // RegionEntity region = regionList.stream().filter(r -> r.getName().contains(data.getRegion())).findFirst().orElse(null);
                if (region1 == null) {
                    hasError.value = true;
                    data.setRegion1(data.getRegion1() + "##城市不存在");
                }

                if (region2 == null) {
                    if (data.getRegion1().contains("济源")) {
                        //济源没有区县
                    } else {
                        hasError.value = true;
                        data.setRegion2(data.getRegion2() + "##区县不存在");
                    }
                }

                if (region1 != null && region2 != null) {
                    data.setRegionCode(region2.getCode());
                    //判断地区和学校 是否具备权限
                    if (isNotEmpty(userDetail.getRegionCode())) {
                        if (String.valueOf(data.getRegionCode()).startsWith(userRegionCodeForPermission)) {
                            //具备权限
                        } else {
                            hasError.value = true;
                            data.setRegion2(data.getRegion2() + "##不具备该地区的权限");
                        }
                    }
                }

                //判断是否具备该学校的权限
                if (isNotEmpty(userDetail.getSchoolCode())) {
                    if (isEquals(schoolForPermission.getName(), data.getSchoolName())) {
                        //具备权限
                    } else {
                        hasError.value = true;
                        data.setSchoolName(data.getSchoolName() + "##不具备该学校的权限");
                    }
                } else {
                    //不需要判断学校权限
                }

                if (isEquals(hasError.value, true)) {
                    userWithErrorListInMap.get(userDetail.getId()).add(data);
                } else {
                    //没有错误的才添加
                    super.list.add(data);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                if (isEquals(hasError.value, true)) {
                    //  有错误, 不入库
                } else {
                    studentService.saveStudentWidthSchoolAndClass(super.list);
                }
            }
        }.start(2);

        if (Objects.equals(hasError.value, true)) {
            String errorFileName = file.getOriginalFilename().replace(".xlsx", "错误提示.xlsx");
            export(response, errorFileName, userWithErrorListInMap.get(userDetail.getId()));
        } else {
            PrintWriter pw = response.getWriter();
            //逻辑删除导入学籍时学籍不存在的学校班级(当前学期)
            schoolService.deleteBySchoolCode();
            gradeClassService.deleteByClassCode();
            //恢复导入学籍时学籍存在但逻辑删除的学校班级(当前学期)
            schoolService.updateBySchoolCode();
            gradeClassService.updateByClassCode();
            pw.write(ZsJson.toJson(new Result<>()));
            pw.close();
        }
        System.out.println("excel解析完成");
    }

下载一个后端返回的流文件

注意跨域问题

后端解决跨域问题

const downLoadExport=()=>{
  axios({
    method: 'post',
    url: baseUrl+"/electric/electricassets/download/assets",
    headers: {
      "Content-Type": "application/json;charset=UTF-8",
      "token":getToken()
    },
    responseType: 'blob'
  }).then(response => {
    if (Object.values(response.headers)[0]=='application/vnd.ms-excel;charset=UTF-8'){
      const url = window.URL.createObjectURL(new Blob([response.data]));
      // 创建a标签,并隐藏a标签
      let link = document.createElement('a')
      link.style.display = 'none'
      // a标签的href属性指定下载链接
      link.href = url
      //setAttribute() 方法添加指定的属性,并为其赋指定的值
      // 后缀格式.csv/.xsls要和需要和后端返回格式相同,这里以.csv为例
      link.setAttribute('download',   '文件名称.xlsx')
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }
  })
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1197233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java 进阶篇】Java 中 JQuery 对象和 JS 对象:区别与转换

在前端开发中&#xff0c;经常会涉及到 JavaScript&#xff08;JS&#xff09;和 jQuery 的使用。这两者都是前端开发中非常重要的工具&#xff0c;但它们之间存在一些区别。本文将详细介绍 Java 中的 JQuery 对象和 JS 对象的区别&#xff0c;并讨论它们之间的转换方法。 1. …

多状态Dp问题——买卖股票的最佳时机含冷冻期

目录 一&#xff0c;题目 二&#xff0c;题目接口 三&#xff0c;解题思路及其代码 一&#xff0c;题目 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成…

张小泉的“老字号”快守不住了:限期整改,业绩和产品各有危机

撰稿|行星 来源|贝多财经 11月8日&#xff0c;商务部等5部门发布了中华老字号的复核结果。结果显示&#xff0c;全国有981家中华老字号企业通过了复核&#xff0c;73家中华老字号企业附条件通过复核&#xff0c;另有55家企业未能通过复核。 贝多财经发现&#xff0c;张小泉股…

文件改名:避免繁琐操作,利用筛选文件批量重命名技巧优化文件管理

在我们的日常生活和工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;从文档、图片到音频和视频等。在这些情况下&#xff0c;一个高效的文件管理策略至关重要。文件重命名的必要性主要体现在两个方面。首先&#xff0c;对于大量文件&#xff0c;手动进行重命名不仅费…

autollm 指令设计

autollm 指令设计 可循环示意图文本 示意图AI解释可循环示意图 文本 示意图 # <|aos|>环境<|bos|>他人<|cos|>自己<|dos|>表示是否进行写python 代码来从外界获取辅助数据来重构 前面所有的信息<|eos|>代表是否生成python 代码控制各种外审设备…

N-133基于springboot,vue小说网站

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本项…

酷柚易汛ERP-客户管理操作指南

1、应用场景 对客户信息进行管理&#xff0c;可新增客户、设置客户等级、联系人信息、银行账户和销售人员等信息&#xff0c;方便开单时自动匹配销售信息。 2、主要操作 2.1 新增客户 打开【资料】-【客户管理】&#xff0c;点击【新增】。 在页面输入客户信息、联系人地址…

AI系统开发源码搭建的专业深度思考:从零到一的技术探索之路

【内容摘要】 随着人工智能技术的飞速发展&#xff0c;AI系统开发源码搭建已成为越来越多开发者关注的焦点。本文将从专业角度探讨AI系统开发源码搭建的过程&#xff0c;从需求分析、设计、开发、测试到部署&#xff0c;深入挖掘其中的关键技术和挑战。同时&#xff0c;我们将…

ROS 学习应用篇(二)话题Topic学习之话题的发布与订阅

顾名思义&#xff0c;这是一个异步的消息传达过程 首先是消息的发布&#xff0c;接着是消息的订阅 话题发布 由发布者发布一个“消息”的数据结构&#xff0c;再由订阅者订阅这个消息结构。 再开始撰写一段程序之前&#xff0c;我们需要在程序代码中引入库→节点初始化→创…

前端开发入门笔记(八)CSS3属性详解:动画详解+Flex布局图文详解+Web字体

参考链接&#xff1a;https://web.qianguyihao.com/02-CSS%E5%9F%BA%E7%A1%80/12-CSS3%E5%B1%9E%E6%80%A7%E8%AF%A6%E8%A7%A3%EF%BC%9A%E5%8A%A8%E7%94%BB%E8%AF%A6%E8%A7%A3.html#_3%E3%80%81%E6%97%8B%E8%BD%AC%EF%BC%9Arotate 过渡 transition的中文含义是过渡。过渡是CSS…

【数据结构】深度剖析ArrayList

目录 ArrayLIst介绍 ArrayList实现的接口有哪些&#xff1f; ArrayList的序列化&#xff1a;实现Serializable接口 serialVersionUID 有什么用? 为什么一定要实现Serialzable才能被序列化&#xff1f; transient关键字 为什么ArrayList中的elementData会被transient修…

C++ 常用方法,刷oj必备(持续更新!!!)

输出结果保留小数点后n位(4位) #include<iostream> #include <iomanip> using namespace std;int main(){double s ;cin >> s ;cout<<fixed << setprecision(4) << s ;return 0; } 类型转换 string 转 int #include <iostream> …

耗时3年写了一本数据结构与算法pdf!开源了

前言 大家好&#xff0c;我是bigsai&#xff0c;很早就在写博客&#xff0c;我将csdn的文章整理成了一个pdf&#xff0c;并且开源到github上&#xff01; 自己写东西断断续续也不少时间了&#xff0c;也写了不少东西(虽然是偏向小白)&#xff0c;这个其实花费的时间还是比较多…

SQL 聚合函数

前言 SQL中的聚合函数是对一组值执行计算&#xff0c;并返回单个值的函数。 常用的聚合函数有&#xff1a; 函数作用AVG&#xff08;&#xff09;求平均值MAX&#xff08;&#xff09;求最大值MIN&#xff08;&#xff09;求最小值SUM&#xff08;&#xff09;求和COUNT&…

Windows 中 kubectl 配置详细指南

目录 前言 什么是 Chocolatey与Minikube Chocolatey Minikube 安装 Minikube 安装 Chocolatey&#xff08;如果尚未安装&#xff09; Minikube 遇到的问题 通过获取集群状态的方法 kubectl 可选配置和插件 启用 shell 自动补全功能 安装 kubectl convert 插件 前言 …

C语言、c++史上最全最全爱心代码大全,彩色闪动、字符填充,附源码

第一种&#xff1a;红色爱心代码 直接上代码&#xff1a; #include<stdio.h> #include<Windows.h> int main() {system(" color 0c");//设计程序颜色 printf("遇见你是一件很开心的事情,爱你哟&#xff01;&#xff01;&#xff01;\n");//打…

【神经网络】GAN:生成对抗网络

GAN&#xff1a;生成对抗网络 Generator&#xff08;生成器&#xff09;概念 和传统的神经网络不同&#xff0c;Generator除了接受x的输入之外&#xff0c;还会接受一个简单的分布作为z进行输入&#xff0c;从而使得网络的输出也是一个复杂的分布 为什么输出需要时一个分布呢…

RocketMQ(一):基本概念和环境搭建

Spring源码系列文章 RocketMQ(一)&#xff1a;基本概念和环境搭建 目录 一、RocketMQ简介二、各个MQ产品的比较三、RocketMQ重要概念1、基本概念2、消息从发送到被消费的的流程3、生产和消费理解 四、RocketMQ安装1、下载RocketMQ2、解压并配置环境变量3、修改nameServer的运行…

JVM之jmap java内存映射工具

jmap java内存映射工具 1、jmap jdk安装后会自带一些小工具&#xff0c;jmap命令(Memory Map for Java)是其中之一。主要用于打印指定Java进程(或核 心文件、远程调试服务器)的共享对象内存映射或堆内存细节。 jmap命令可以获得运行中的jvm的堆的快照&#xff0c;从而可以离…

超强C语言跨年烟花代码,精美无比,附源码分步解析

现在大家是不是都觉得程序员不懂浪漫&#xff1f;那真的大错特错&#xff0c;今天就让你们看看什么是程序员的浪漫&#xff01; 我们今天就来写写《烟花》表白程序&#xff0c;不要惊讶&#xff0c;不要激动&#xff0c;学会了快去拿给心中的那个人看&#xff01;&#xff01;…