前端代码:
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()">
×
</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()">
×
</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()">×</a>
<strong>SUCCESS!</strong> JRXML file generated successfully!
</div>
</div>
</body>
</html>