使用Axios从前端上传文件并且下载后端返回的文件

前端代码:

function uploadAndDownload(){
            showLoading();
            const fileInput = document.querySelector('#uploadFile');
            const file = fileInput.files[0];

            const formData = new FormData()
            formData.append('file', file)

            return new Promise((resolve, reject) => {
                axios({
                    url: '/generateJrxml',
                    method: 'post',
                    data: formData,
                    responseType: 'blob',
                    headers: {
                     'Content-Type': 'multipart/form-data'
                    }
                }).then(res => {
                    const { data, headers } = res
                    const fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
                    const blob = new Blob([data], {type: headers['content-type']})
                    let dom = document.createElement('a')
                    let url = window.URL.createObjectURL(blob)
                    dom.href = url
                    dom.download = decodeURI(fileName)
                    dom.style.display = 'none'
                    document.body.appendChild(dom)
                    dom.click()
                    dom.parentNode.removeChild(dom)
                    window.URL.revokeObjectURL(url)
                    })
                    .catch(e => {
                        console.log(e)
                        reject(e)
                    })
            })
        }

后端代码 

    @PostMapping(value = "/generateJrxml", produces = "application/json")
    ResponseEntity<InputStreamResource> generateJrxmlFromExcel(@RequestParam("file") MultipartFile uploadFile){
        try {
            String fileContent = jasperJrxmlGenerateService.generateJrxmlFile(uploadFile)
            byte[] bytes = fileContent.getBytes("UTF-8")
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes)
            HttpHeaders headers = new HttpHeaders()
            headers.add("Content-Disposition", "attachment;filename=" + uploadFile.getOriginalFilename().takeBefore('.') + ".jrxml")
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(new InputStreamResource(bais))
        }catch(Exception e){
            HttpHeaders headers = new HttpHeaders()
            return ResponseEntity.internalServerError().headers(headers)
        }
    }

完整的前端代码如下: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="jasper.css">
    <title>Jasper Helper</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"/>
<!--    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>-->
<!--    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>-->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    <script type="text/javascript">
        function clickUpload(){
            document.getElementById("uploadFile").click();
        }

        function showFileName(files){
            const fileName = files[0].name;
            document.getElementById("file-name").innerHTML = fileName;
        }

        function showLoading(){
            var file = document.getElementById("uploadFile").value;
            if(file == ''){
                console.error("please upload file!");
                alertFileMissing();
            }else{
                document.querySelector('#load-icon').style.display = "inline-block";
                console.log('loading')
            }
        }

        function closeLoading(){
            document.querySelector('#load-icon').style.display = "none";
            console.log('end loading')
        }

        function closeAlert(){
            document.querySelector('#alert').style.display = "none";
        }

        function alertFileMissing(){
             document.querySelector('#alert').style.display = "inline-block";
        }

        function closeAlertSuccess(){
            document.querySelector('#alertSuccess').style.display = "none";
        }

        function alertSuccess(){
             document.querySelector('#alertSuccess').style.display = "inline-block";
        }

        function closeAlertFailure(){
            document.querySelector('#alertFailure').style.display = "none";
        }

        function alertFailure(){
             document.querySelector('#alertFailure').style.display = "inline-block";
        }

        function uploadAndDownload(){
            showLoading();
            const fileInput = document.querySelector('#uploadFile');
            const file = fileInput.files[0];

            const formData = new FormData()
            formData.append('file', file)

            return new Promise((resolve, reject) => {
                axios({
                    url: '/generateJrxml',
                    method: 'post',
                    data: formData,
                    responseType: 'blob',
                    headers: {
                     'Content-Type': 'multipart/form-data'
                    }
                }).then(res => {
                    closeLoading()
                    const { data, headers } = res
                    const fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
                    const blob = new Blob([data], {type: headers['content-type']})
                    let dom = document.createElement('a')
                    let url = window.URL.createObjectURL(blob)
                    dom.href = url
                    dom.download = decodeURI(fileName)
                    dom.style.display = 'none'
                    document.body.appendChild(dom)
                    dom.click()
                    dom.parentNode.removeChild(dom)
                    window.URL.revokeObjectURL(url)
                    alertSuccess()
                    })
                    .catch(e => {
                        closeLoading()
                        console.log(e)
                        alertFailure()
                        reject(e)
                    })
            })
        }


    </script>
</head>
<body class="jasper-wrap">
    <div class="container overflow-hidden text-center">
        <br/><br/><br/><br/><br/><br/><br/><br/>
        <h3>Jasper Helper</h3>
        <br/>
<!--        <form id="upload-form" action="/generateJrxml" method="post" enctype="multipart/form-data">-->
        <form id="upload-form">
            <input type="file" id="uploadFile" name="file" accept=".xlsx,.xls" style="display:none;" onchange="showFileName(this.files)" required>
            <button type="button" class="btn btn-outline-primary" onclick="clickUpload()">
                <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor" class="bi bi-file-earmark-arrow-up-fill" viewBox="0 0 16 16">
                    <path d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0M9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1M6.354 9.854a.5.5 0 0 1-.708-.708l2-2a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 8.707V12.5a.5.5 0 0 1-1 0V8.707z"/>
                </svg>
                UPLOAD
            </button>
            <br/>
            <div id="file-name"></div>
            <br/>
            <button type="button" class="btn btn-success" onclick="uploadAndDownload()">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle" viewBox="0 0 16 16">
                <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
                <path d="m10.97 4.97-.02.022-3.473 4.425-2.093-2.094a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05"/>
                </svg>
                GENERATE
            </button>
        </form>
        <div class="container mt-3">
            <div class="spinner-border text-info" id="load-icon" style="display:none"></div>
        </div>

        <div id="alert" class="alert alert-warning" style="display:none">
            <a href="#" class="close" data-dismiss="alert" onclick="closeAlert()">
                &times;
            </a>
            <strong>ERROR!</strong>Please upload file!
        </div>

        <div id="alertFailure" class="alert alert-warning" style="display:none">
            <a href="#" class="close" data-dismiss="alert" onclick="closeAlertFailure()">
                &times;
            </a>
            <strong>ERROR!</strong>Failed to generate JRXML file!
        </div>

        <div id="alertSuccess" class="alert alert-success" style="display:none">
            <a href="#" class="close" data-dismiss="alert" onclick="closeAlertSuccess()">&times;</a>
            <strong>SUCCESS!</strong> JRXML file generated successfully!
        </div>

    </div>
</body>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32——GPIO篇

技术笔记&#xff01; 1. 什么是GPIO&#xff1f; GPIO是通用输入输出端口&#xff08;General-purpose input/output&#xff09;的英文简写&#xff0c;是所有的微控制器必不可少的外设之一&#xff0c;可以由STM32直接驱动从而实现与外部设备通信、控制以及采集和捕获的功…

wordpress子比主题美化-为图文列表封面添加动态缩略图特效 多种效果演示

wordpress子比主题-为图文列表文章封面添加动态缩略图特效 给自己子比主题加一个列表文章封面添加动态缩略图 直接复制以下代码&#xff0c;添加到主题自定义CSS代码中即可&#xff0c;下图为效果演示 wordpress子比主题-为图文列表文章封面添加动态缩略图特效 给自己子比主题…

MySQL①——数据库与表格的创建

今日任务&#xff1a; 创建一个名为“db_classes”的数据库 创建一行名为“db_hero”的表 将四大名著中的常见人物插入这个英雄表 数据库的创建与删除 create 命令&#xff08;创建&#xff09;&#xff1a; create database 数据库名&#xff1b;#参数默认create database …

Spring MVC(上)

initApplicationEventMulticaster为上下文初始化 simpleApplicationEventMulticaster怎么处理广播事件的 refisterListeners注册监听器 finishBeanFactoryInitialization初始化非延迟bean 惰性初始化 dispatcherServlet的初始化 servletConfigPropertyValues创建propertyValues…

虚拟化技术 安装并配置ESXi服务器系统

安装并配置ESXi服务器系统 一、实验目的与要求 1.掌握创建VMware ESXi虚拟机 2.掌握安装VMware ESXi系统 3.掌握配置VMware ESXi系统的管理IP 4.掌握开启VMware ESXi的shell和ssh功能的方法 二、实验内容 1.安装VMware workstation 15或更高版本 2.创建VMware ESXi虚拟…

软件杯 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

分布式事务—> seata

分布式事务之Seata 一、什么是分布式事务&#xff1f; 分布式事务是一种特殊类型的事务&#xff0c;它涉及多个分布式系统中的节点&#xff0c;包括事务的参与者、支持事务的服务器、资源服务器以及事务管理器。 在分布式事务中&#xff0c;一次大型操作通常由多个小操作组成…

排序算法--直接选择排序

前提&#xff1a; 选择排序&#xff1a;选择排序(Selection sort)是一种比较简单的排序算法。它的算法思想是每一次从待排序的数据元素中选出最小(或最大)的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完。 话不多说&#xff0c;直接放图…

ResponseHttp

文章目录 HTTP响应详解使用抓包查看响应报文协议内容 Response对象Response继承体系Response设置响应数据功能介绍Response请求重定向概述实现方式重定向特点 请求重定向和请求转发比较路径问题Response响应字符数据步骤实现 Response响应字节数据步骤实现 HTTP响应详解 使用抓…

Web前端一套全部清晰 ⑥ day4 CSS.1 基础选择器、文字控制属性

后来的我不在抱怨 所有的事与愿违都是我能力或者判断力不足 仅此而已 —— 24.5.1 一、CSS定义 1. 将CSS放在html文件的<style>标签中 层叠样式表(Cascading style Sheets&#xff0c;缩写为 CSS)&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现(美…

LeetCode 面试经典150题 28.找出字符串中第一个匹配项的下标

题目&#xff1a;给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 思路&#xff1a;暴力&#xff08;…

Pyside6详细使用教程python之GUI开发

1、首先需要安装Pyside6&#xff0c;终端执行命令&#xff1a; pip3.10 install pyside6 2、你们的一般是 pip install pyside6 2、如下代码创建一个简易程序导入必要的模块 import sys from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton,…

【docker】常用的Docker编排和调度平台

常用的Docker编排和调度平台 Kubernetes (K8s): Kubernetes是目前市场上最流行和功能最全面的容器编排和调度平台。它由Google开发并开源&#xff0c;现由CNCF&#xff08;云原生计算基金会&#xff09;维护。Kubernetes设计用于自动化容器部署、扩展和管理&#xff0c;支持跨…

出现nan nan

试着修改训练集大小或者batch_size大小&#xff0c;令训练集大小为batch_size的整数倍&#xff0c;不行 的话&#xff0c;看环境问题

8.k8s中网络资源service

目录 一、service资源概述 二、service资源类型 1.ClusterIP类型 2.service的nodeport类型 3.service的loadbalancer类型&#xff08;了解即可&#xff09; 4.service的externalname类型&#xff08;了解即可&#xff09; 三、nodeport的端口范围设置和svc的endpoint列表 1.修…

Jupyter Notebook魔术命令

Jupyter Notebook是一个基于网页的交互式笔记本&#xff0c;支持运行多种编程语言。 Jupyter Notebook 的本质式一个Web应用程序&#xff0c;便于创建和共享文学化程序文档&#xff0c;支持实现代码&#xff0c;数学方程&#xff0c;可视化和markdown。用途包括&#xff1a;数据…

Redis 实战2

系列文章目录 本文将从字典的实现、哈希算法、解决键冲突、rehash、渐进式rehash几方面来阐述 Redis 实战Ⅱ 系列文章目录字典的实现哈希算法解决键冲突rehash渐进式 rehash渐进式 rehash 执行期间的哈希表操作 字典 API总结 字典的实现 Redis 的字典使用哈希表作为底层实现&…

解决layui的bug 在layui tree 组件中 禁用选中父节点后自动选中子节点功能

最近做权限管理后台&#xff0c;用了layui tree 组件&#xff0c;发现选中了父节点后&#xff0c;自动选中了子节点。不满足现实业务需求。所以微调了下源代码。 在用树形组件中&#xff0c;在用文档中 tree.setChecked(demoId, [2, 3]); //批量勾选 id 为 2、3 的节点 用这句…

All In ai,Oracle 23C没了,等来了Oracle 23ai

今年一月份的Blog介绍Oracle命名规则的时候&#xff0c;说到Oracle的命名是紧紧跟随时代浪潮的前言科技的&#xff0c;在文章的最后还大胆预测也许Oracle的下一个版本就叫25A了&#xff0c;结果Oracle根本等不及&#xff0c;把原来已经海量宣传的Oracle 23C直接改名为23ai&…

【Mac】Lightroom Classic 2024 v13.1安装教程

软件介绍 Lightroom Classic 2024是Adobe公司推出的一款专业的数字图像处理软件&#xff0c;旨在为摄影师提供强大的工具和功能&#xff0c;以管理、编辑和分享他们的照片作品。以下是Lightroom Classic 2024的主要特点和功能&#xff1a; 数字照片管理&#xff1a; 提供直观…
最新文章