使用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>

上一篇:《Beginning C++20 From Novice to Professional》第八章 Defining Functions


下一篇:Java Lambda表达式