浏览器文件上传和下载
前言:以下代码如果有一些类无法导入的,可以自行查资料替换!!!
1.上传
前端vue
-
编写按钮
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleUpload" v-hasPermi="['client:clientManagement:upload']" >上传</el-button>
-
打开上传弹窗
/** 上传 */ handleUpload() { this.open = true; this.title = "上传客户端"; },
-
编写弹窗 el-upload 绑定事件作用详情自己看官方网站
<!-- 上传客户端 --> <el-dialog class="printercloud-dialog" :visible.sync="open" width="400px" append-to-body> <div slot="title" class="dialog-title"> <span>{{title}}</span> </div> <el-upload class="upload-demo" drag ref="upload" :limit="1" accept=".zip" :headers="upload.headers" :action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :on-change="handleChange" :on-remove="handleChange" :before-upload="beforeUpload" :file-list="fileList" :auto-upload="false"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <div class="el-upload__tip" slot="tip">只能上传zip文件</div> </el-upload> <div slot="footer" class="dialog-footer"> <el-button @click="open = false">取 消</el-button> <el-button type="primary" @click="submitForm" v-hasPermi="['client:clientManagement:upload']">确 定</el-button> </div> </el-dialog>
-
定义相关参数
// 弹出层标题 title: "", // 是否显示弹出层 open: false, // 上传参数 upload: { // 是否显示弹出层(用户导入) open: false, // 弹出层标题(用户导入) title: '', // 是否禁用上传 isUploading: false, // 是否更新已经存在的用户数据 updateSupport: 0, // 设置上传的请求头部 权限token headers: { Authorization: xxx }, // 上传文件访问的后端地址 url: /xxx/xxx, }, fileList: [],
-
定义相关方法
/** 弹框确认上传按钮 */ submitForm() { if (!this.fileList || this.fileList <= 0) { this.$modal.msgWarning('请选择需要上传的客户端!') return } this.$refs.upload.submit() }, // 文件上传中处理 handleFileUploadProgress(event, file, fileList) { this.upload.isUploading = true }, // 文件上传成功处理 handleFileSuccess(response, file, fileList) { this.upload.open = false this.upload.isUploading = false this.$refs.upload.clearFiles() if (response.code === 200) { this.$modal.msgSuccess(response.msg) this.getList() } else { this.$modal.msgError(response.msg) } }, // 文件列表添加删除触发 handleChange(file, fileList) { this.fileList = fileList; }, // 上传去前校验 beforeUpload(file) { const isJPG = file.type === 'application/zip'; // const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG) { this.$modal.msgError('上传文件只能是 ZIP 格式!'); } /* if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } */ // return isJPG && isLt2M; return isJPG; },
后端
-
Controller接口
/** * 上传客户端 */ @PostMapping(value = "/uploadClient", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public AjaxResult uploadClient(@ApiParam(value = "待上传文件",required = true) @RequestParam("file") MultipartFile file) throws Exception { return clientManagementService.uploadClient(file); }
-
Service实现
/** * 上传客户端 * @param multipartFile * @return */ @Override @Transactional public AjaxResult uploadClient(MultipartFile multipartFile) throws Exception { //创建临时目录 因为入参是MultipartFile类型,所以需要先转换成File类型,暂存在本地用于上传,上传后删除 String parentPath = BasConfig.getUploadPath() + File.separator + IdUtils.fastSimpleUUID(); File tempFileDir = new File(parentPath); if(!tempFileDir.exists()) { tempFileDir.mkdirs(); } try { String originalFilename = multipartFile.getOriginalFilename(); // 获取文件后缀 String prefix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); // 客户端名称 String clientName = originalFilename.substring(0, originalFilename.lastIndexOf(".")); // 根据客户端名称判断重复 List<ClientManagement> clientList = clientManagementMapper.getClientManagementListByClientName(clientName); if (clientList != null && clientList.size() > 0) { return AjaxResult.error("客户端名称已存在"); } // 用id作为文件名,防止生成的临时文件重复 File file = new File(parentPath, IdUtils.fastSimpleUUID() + "." + prefix); if(!file.exists()) { file.createNewFile(); } multipartFile.transferTo(file); // 文件的存储位置 String fileID = FileServerUtils.upload(file, BasConfig.getUploadPath()+File.separator + "client/", true); //存到临时文件表 ClientManagement client = new ClientManagement(); // 获取当前用户 LoginUser loginUser = SecurityUtils.getLoginUser(); SysUser user = loginUser.getUser(); client.setId(IdUtils.fastSimpleUUID()); client.setClientName(clientName); client.setFileId(fileID); client.setFileType(prefix); client.setVersion("1"); client.setIsUniversal(0); client.setCreateBy(user.getUserName()); client.setCreateTime(LocalDateTime.now()); client.setUpdateBy(user.getUserName()); client.setUpdateTime(LocalDateTime.now()); // 保存客户端记录 clientManagementMapper.insertClientManagement(client); return AjaxResult.success("客户端上传成功"); } catch (Exception e) { e.printStackTrace(); return AjaxResult.error("客户端上传失败"); } finally { // 删除本地临时文件 delFile(tempFileDir); } } //删除临时文件 private boolean delFile(File file){ if(!file.exists()){ return false; } if(file.isDirectory()){ File[] files = file.listFiles(); for(File f :files){ delFile(f); } } return file.delete(); }
2.下载
前端vue
-
下载按钮
<el-button type="success" plain icon="el-icon-bottom" size="mini" @click="handleDownload" >下载</el-button>
-
相关方法
/** 下载操作 */ handleDownload(row) { const id = row.id ? row.id : this.ids[0] request({ url: '/xxx/xxx/' + id + '?Authorization=' + 'xxx',// 路径、参数列表数据id、请求权限Authorization method: 'get', responseType: 'blob',// 响应类型,blob通过浏览器下载 }).then((res) => { // 我这里下载的是zip压缩包,所以正常下载type返回是application/zip,如果发生异常下载失败,返回的是application/json if (res.size > 0 && res.type === 'application/zip') { const content = res const blob = new Blob([content]) if ('download' in document.createElement('a')) { // 非IE下载 const elink = document.createElement('a') elink.download = this.selectData[0].clientName + '.' + this.selectData[0].fileType elink.style.display = 'none' elink.href = URL.createObjectURL(blob) document.body.appendChild(elink) elink.click() URL.revokeObjectURL(elink.href) // 释放URL 对象 document.body.removeChild(elink) } else { // IE10+下载 navigator.msSaveBlob(blob, fileName) } } else { this.$modal.msgError('客户端下载失败') } }) },
后端
-
Controller接口
/** * 下载客户端 */ @GetMapping("/downloadClient/{id}") public void downloadClient(HttpServletResponse response, @PathVariable("id") @NotNull String id) throws Exception { clientManagementService.downloadClient(response, id); }
-
Service实现
/** * 下载客户端 * @param response * @param id * @return */ @Override public void downloadClient(HttpServletResponse response, String id) throws Exception { // 根据id获取客户端信息 ClientManagement client = clientManagementMapper.getClientManagementById(id); if (client == null) { throw new ValidDataException("客户端信息不存在"); } // 文件再服务器上的索引 String fileId = client.getFileId(); if (StringUtils.isEmpty(fileId)) { throw new ValidDataException("服务器客户端文件不存在"); } OutputStream os = null; InputStream fis = null; try { // 根据文件索引,下载服务器的文件 File file = FileServerUtils.download(fileId, null); fis = new FileInputStream(file); String formFileName = new String(client.getClientName().getBytes("UTF-8"), "ISO-8859-1"); response.setContentType("application/zip");// 指定下载的类型,如果需要兼容下载多种类型可以自行去查资料 response.setHeader("Content-Disposition", "attachment;filename=" + formFileName); os = response.getOutputStream(); byte[] b = new byte[fis.available()]; int len; while ((len = fis.read(b)) > 0) { os.write(b, 0, len); } os.flush(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("客户端下载失败"); } finally { try { if (os != null) { os.close(); } if (fis != null) { fis.close(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("客户端下载失败"); } } }
3.文件存取工具类FileServerUtils(也可以自行查找资料)
package com.startdima.printerCloud.common.utils;
import com.startdima.bas.common.config.BasConfig;
import com.startdima.bas.common.utils.StringUtils;
import com.startdima.common.pojo.FileResult;
import com.startdima.common.pojo.Server;
import com.startdima.file.FileServiceControl;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 文件存取操作工具类
*/
@Component
public class FileServerUtils {
private static final Logger logger = LoggerFactory.getLogger(FileServerUtils.class);
private static String tempPath;
private static Server server;
// 配置文件中配置的服务器路径
@NotNull(message = "文件服务器配置不能为空")
@Value("${serverParam}")
public void setServerParam(String serverParam) {
// 设置文件服务器配置
try {
FileServerUtils.server = new Server();
JSONObject jsonObject = JSONObject.fromObject(serverParam);
server.setServerParam(jsonObject.toString());
server.setServerCode(jsonObject.getString("serverCode"));
server.setServerType(jsonObject.getString("serverType"));
} catch (Exception e) {
logger.error("初始化文件服务器配置发生错误,错误原因:" + e.getMessage(), e);
}
}
@Resource
public void setTempPath(BasConfig basConfig) {
String profile = basConfig.getProfile();
FileServerUtils.tempPath = profile + (profile.endsWith("/") ? "" : "/") + "temp";
// 设置缓存文件夹
try {
File file = new File(tempPath);
if (!file.exists())
file.mkdirs();
} catch (Exception e) {
logger.error("初始化文件操作工具类缓存文件夹发生错误,错误原因:" + e.getMessage(), e);
}
}
/**
* 判断是否为文件服务器文件id
*/
public static boolean hasServerFile(String fileId) {
String serverCode = server.getServerCode();
return fileId.startsWith(serverCode + "/");
}
/**
* 文件服务器文件上传
*
* @param file 待上传文件
* @param storePath 文件服务器上的存储目录
* @param delete 上传成功后是否删除本地文件
* @return 上传后的文件名
*/
public static String upload(File file, String storePath, boolean delete) throws Exception {
String filename = file.getName();
String namePrefix = filename.substring(0, filename.lastIndexOf("."));
String nameSuffix = filename.substring(filename.lastIndexOf(".") + 1);
// 上传的文件名
String storeFileName = namePrefix + getTimeStr() + '.' + nameSuffix;
// 上传文件
FileResult fileResult = FileServiceControl.upload(server, storePath, file, storeFileName, 600);
if (!fileResult.isFlag()) throw new Exception(fileResult.getMessage());
String fileId = fileResult.getMessage();
if (file.exists() && delete) file.delete();
return fileId;
}
/**
* 文件下载
*
* @param fileId 文件id
* @param downPath 下载路径
* @return 文件
* @throws Exception 异常情况
*/
public static File download(String fileId, String downPath) throws Exception {
// 下载路径,为空则默认缓存路径
if (StringUtils.isEmpty(downPath)) {
downPath = tempPath;
} else {
downPath = downPath.endsWith("/") ? downPath : downPath + "/";
File pathFile = new File(downPath);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
}
File file = new File(downPath + fileId.substring(fileId.lastIndexOf("/") + 1));
if (file.exists()) return file;
// 文件id切割前缀
fileId = fileId.substring(fileId.indexOf('/'));
FileResult result = FileServiceControl.download(server, fileId);
if (!result.isFlag()) throw new Exception(result.getMessage());
result.getFile().renameTo(file);
return file;
}
/**
* 删除服务器上的文件
*
* @param fileId 文件id
*/
public static boolean delete(String fileId) {
if (StringUtils.isEmpty(fileId)) return true;
// 删除服务器上的文件
FileResult result = FileServiceControl.delete(server, fileId);
if (!result.isFlag()) throw new RuntimeException(result.getMessage());
return true;
}
/**
* 获取时间串
*/
private static String getTimeStr() {
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
}