Vue的APP实现下载文件功能,并将文件保存到手机中
文字说明
本文介绍Vue实现的APP,将文件下载并保存到手机中,为系统提供导出功能;同时支持导入,即选择本地的文件后,获取文件内容,并将其上传到服务器中,也可选择对上传的文件内容进行解析,为系统提供导入功能
附带讲解视频,主要实验Vue的5+App的文件上传和下载功能
后台核心代码
后端控制器代码(上传接口)
java
package com.boot.controller;
import com.boot.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
/**
* @author bbyh
* @date 2024/6/4 22:58
*/
@RestController
@Slf4j
@CrossOrigin(origins = "*", maxAge = 3600)
public class UploadController {
@PostMapping("/upload")
public Result upload(@RequestBody MultipartFile file) {
try {
InputStream inputStream = file.getInputStream();
byte[] buf = new byte[inputStream.available()];
int read = inputStream.read(buf);
String fileContent = new String(buf, 0, read);
log.info("文件名称:{},文件内容:{}", file.getOriginalFilename(), fileContent);
return Result.success("文件上传成功", fileContent);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件上传接口接口服务出错", null);
}
}
}
下载接口
java
package com.boot.controller;
import com.boot.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author bbyh
* @date 2024/6/4 22:45
*/
@RestController
@Slf4j
@CrossOrigin(origins = "*", maxAge = 3600)
public class DownloadController {
@Value("${file.path}")
private String filePath;
@GetMapping("/download/{fileName}")
public void download(@PathVariable String fileName, HttpServletResponse response) {
try {
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
try (InputStream inputStream = Files.newInputStream(Paths.get(filePath + fileName))) {
byte[] buf = new byte[inputStream.available()];
int read = inputStream.read(buf);
response.getOutputStream().write(buf, 0, read);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
response.reset();
Result.writeResult(response, "文件下载接口接口服务出错," + e.getMessage());
}
}
}
前台核心代码
页面主要代码
html
<template>
<div style="display: flex; justify-content: center; align-items: center; height: 100px; width: 100%">
<el-button type="primary" @click="selectFile()">选择文件上传</el-button>
<el-button type="danger" @click="openDownloadDialog()">下载文件</el-button>
<input type="file" style="display: none" @change="uploadFile($event)" ref="uploadFileRef">
</div>
<el-dialog title="文件下载" width="60%" v-model="data.dialog">
<el-input v-model="data.fileName" placeholder="请输入下载文件名"/>
<template #footer>
<span class="dialog-footer">
<el-button @click="data.dialog = false">取消</el-button>
<el-button type="primary" @click="downloadFile">确认下载</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {downloadFileToLocal, message, postRequest} from "./util";
import {reactive, ref} from "vue";
function uploadFile(event) {
if (event.target.files.length === 0) {
message("warning", "本次未选择文件");
return;
}
const formData = new FormData();
const file = event.target.files[0];
formData.append("file", file, file.name);
postRequest("/upload", formData).then((res) => {
if (res.data.code === 200) {
message("success", res.data.data);
} else if (res.data.code === 500) {
message("error", res.data.msg);
}
});
}
const uploadFileRef = ref();
async function selectFile() {
uploadFileRef.value.click();
}
const data = reactive({
fileName: undefined,
dialog: false,
});
function openDownloadDialog() {
data.fileName = undefined;
data.dialog = true;
}
function downloadFile() {
downloadFileToLocal("/download/" + data.fileName, data.fileName);
}
</script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
</style>
工具类代码
javascript
import axios from "axios";
import {ElMessage} from "element-plus";
const baseUrl = "http://127.0.0.1:5000";
export const downloadFileToLocal = (href, filename) => {
const eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
eleLink.href = baseUrl + href;
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
}
export function message(type, msg) {
ElMessage({
message: msg,
type: type,
center: true,
showClose: true,
})
}
export const postRequest = (url, data) => {
return axios({
method: 'post',
url: baseUrl + url,
data: data,
})
}
运行截图
页面运行效果