2.0 文件上传代码 (上面有公共的下面提供Controller与ServiceImpl接口)
/** * 上传接口文件 * @param multipartFile * @param request * @param fileType * @param filePageType * @return */ @RequestMapping(value ="/updateFile" ,method = RequestMethod.POST) @ResponseBody //@RequestParam()注解的参数要和前端代码name属性值对应 public MsgContext updateFile(@RequestParam("file") MultipartFile multipartFile,HttpServletRequest request, @RequestParam("fileType") String fileType, @RequestParam("filePageType") String filePageType){ try{ //判断文件是否为空 isEmpty if (multipartFile == null){ return MsgContext.createErrorContext("上传文件为空"); } MultipartFile uploadFile = getSingleFile(request); Long id = dsService.updateFile(request, uploadFile,fileType,filePageType); return MsgContext.createSuccessContext("新增成功", id); }catch (Exception e) { return MsgContext.createErrorContext("上传失败"); } }
/** * 上传文件 * * @throws IOException */ @Override @Transactional(readOnly = false) public Long updateFile(HttpServletRequest request, MultipartFile multipartFile, String fileType, String filePageType) throws ServiceException { // 获取文件的原名称 getOriginalFilename 后缀 String OriginalFilename = multipartFile.getOriginalFilename(); if (!(OriginalFilename.endsWith(".xlsx") || OriginalFilename.endsWith(".xls") || OriginalFilename.endsWith(".txt"))) { throw new ServiceException("导入文件格式错误,请导入xlsx/xls/txt格式的文件!"); } String name = OriginalFilename.substring(0, OriginalFilename.indexOf(".")); // 获取时间戳和文件的扩展名,拼接成一个全新的文件名; 用时间戳来命名是为了避免文件名冲突 String fileName = name + "-" + System.currentTimeMillis() + "." + OriginalFilename.substring(OriginalFilename.lastIndexOf(".") + 1); // 定义文件存放路径 String filePath = null; if (filePageType.equals(FileController.FILE_FIRSTLY)) { filePath = remoteBaseUrl + FileController.FILE_FIRSTLY_PATH; } else if (filePageType.equals(FileController.FILE_THIRD)) { filePath = remoteBaseUrl + FileController.FILE_THIRD_PATH; } else { filePath = remoteBaseUrl + FileController.FILE_SECOND_PATH; } // 不存在新增 一个目录(文件夹) 路径+文件名+后缀 File dest = new File(filePath + fileName); // 判断filePath目录是否存在,如不存在,就新建一个 if (!dest.getParentFile().canExecute()) { dest.getParentFile().mkdirs(); // 新建一个目录 } FileDypeVo fileDypeVo = new FileDypeVo(); SimpleDateFormat sdf = new SimpleDateFormat();// 格式化时间 sdf.applyPattern("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); fileDypeVo.setId(IDNexter.getInstance().next()); fileDypeVo.setFileName(fileName); fileDypeVo.setFilePath(filePath); fileDypeVo.setFileType(fileType); fileDypeVo.setFilePageType(filePageType); fileDypeVo.setFilePutDate(sdf.format(date)); LOGGER.info("保存数据" + JSON.toJSONString(fileDypeVo + "OriginalFilename" + OriginalFilename)); int bdCnt = fileMapper.fileinsert(Sutil.checkData(StringUtils.EMPTY, fileDypeVo)); if (bdCnt < 1) { throw new ServiceException("导入文件失败"); } try { // 文件输出 multipartFile.transferTo(dest); } catch (Exception e) { e.printStackTrace(); // 拷贝失败要有提示 return fileDypeVo.getId(); } return fileDypeVo.getId(); }
3.0 文件查询接口代码 (上面有公共的下面提供Controller与ServiceImpl接口)
/** * 查询上传接口 * @param filePageType * @param pageNum * @param pageSize * @return */ @RequestMapping(value ="/selectFile" ,method = RequestMethod.POST) @ResponseBody public MsgContext selectFile(@RequestParam("filePageType") String filePageType, @RequestParam(value = "pageNum",name = "pageNum" ,required = false,defaultValue = "1")Integer pageNum, @RequestParam(value = "pageSize",name = "pageSize",required = false,defaultValue = "1000")Integer pageSize){ try{ //判断文件是否为空 isEmpty if (filePageType == null){ return MsgContext.createErrorContext("类型为空"); } MsgContext mc = new MsgContext(); MyPageInfoVo<FileDypeVo> fInfoVo = dsService.selectFile(pageNum,pageSize,filePageType); mc.addResult("data", fInfoVo); mc.setMsg("查询成功"); return mc; }catch (Exception e) { return MsgContext.createErrorContext("上传失败,原因=》"+e.getMessage()); } }
/** * 查询文件 * */ @Override public MyPageInfoVo<FileDypeVo> selectFile(Integer pageNum, Integer pageSize, String filePageType) { List<FileDypeVo> fileDypeVos = fileMapper.selectFile(filePageType); MyPageInfoVo<FileDypeVo> myPageInfo = new MyPageInfoVo<>(fileDypeVos, pageNum, pageSize); // TODO Auto-generated method stub return myPageInfo; }
4.0 文件预览/下载接口代码 (上面有公共的下面提供Controller与ServiceImpl接口)
isOnLine 默认true在线打开 false下载
/** * 文件预览以及下载接口 * @param response * @param id * @param isOnLine * @return */ @RequestMapping(value ="/downFile" ,method = RequestMethod.POST) @ResponseBody public MsgContext downFile(HttpServletResponse response,@RequestParam("id") Long id, @RequestParam(value = "isOnLine",name = "isOnLine" ,required = false,defaultValue = "true")Boolean isOnLine ){ //isOnLine 默认true在线打开 false下载 try{ //判断文件是否为空 isEmpty if (id == null){ return MsgContext.createErrorContext("id不能为空"); } MsgContext mc = new MsgContext(); FileDypeVo fInfoVo = dsService.downFile(response,id,isOnLine); mc.addResult("data", fInfoVo); mc.setMsg("查询成功"); return mc; }catch (Exception e) { return MsgContext.createErrorContext("下载/预览失败,原因=》"+e.getMessage()); } }
@Override public FileDypeVo downFile(HttpServletResponse response, Long id, Boolean isOnLine) throws IOException { FileDypeVo fileDypeVos = fileMapper.selectFileId(id); String path = fileDypeVos.getFilePath(); String name = fileDypeVos.getFileName(); File file = new File(path+name); LOGGER.info("file==>"+file+"|file.exists()==>"+file.exists()); if (!file.exists()) { throw new ServiceException("未在指定路径发现该文件"+file); } byte[] buf = new byte[1024]; int len = 0; BufferedInputStream br = new BufferedInputStream(new FileInputStream(file)); response.reset(); // 非常重要 if (isOnLine) { // 在线打开方式 URL url = new URL("file:///" + path); response.setContentType(url.openConnection().getContentType()); response.setHeader("Content-Disposition", "inline; filename=" + name); // 文件名应该编码成UTF-8 } else { // 纯下载方式 response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + name); } OutputStream out = response.getOutputStream(); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.close(); // TODO Auto-generated method stub return null;
4.1 下载接口代码 (上面有公共的下面提供Controller与ServiceImpl接口)
下载:Controller
/** * 文件下载接口 * @param response * @param id * @param isOnLine * @return */ @RequestMapping(value ="/printFile" ,method = RequestMethod.POST) @ResponseBody public MsgContext printFile(HttpServletResponse response,@RequestParam("id") Long id) { try{ //判断文件是否为空 isEmpty if (id == null){ return MsgContext.createErrorContext("id不能为空"); } MsgContext mc = new MsgContext(); String fInfoVo = dsService.printFile(id); mc.addResult("data", fInfoVo); mc.setMsg("查询成功"); return mc; }catch (Exception e) { return MsgContext.createErrorContext("预览失败,原因=》"+e.getMessage()); } }
ServerImpl
@Override public FileDypeVo downFile(HttpServletResponse response,Long id){ //根据查询获取地址和文件名 FileDypeVo fileDypeVos = fileMapper.selectFileId(id); String path = fileDypeVos.getFilePath(); String name = fileDypeVos.getFileName(); File file = new File(path + name); LOGGER.info("file==>" + file + "|file.exists()==>" + file.exists()); if (!file.exists()) { throw new ServiceException("未在指定路径发现该文件" + file); } //效验格式后缀 if (!(name.endsWith(".xlsx") || name.endsWith(".xls") || name.endsWith(".txt") || name.endsWith(".pdf") || name.endsWith(".docx") || name.endsWith(".doc") || name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".zip"))) { throw new ServiceException("导入文件格式错误,请导入xlsx/xls/txt/png/doc/docx/pdf/jpg/zip格式的文件!"); } OutputStream os = null; BufferedOutputStream out = null; BufferedInputStream is = null; try { os = response.getOutputStream(); response.reset();// 清空输出流 response.setContentType("application/x-msdownload"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // response.setHeader("Content-disposition", "attachment; filename="+URLEncoder.encode(filename, "UTF-8")+"."+subfix);// 设定输出文件头 //开始下载 name 是有后缀的 ab.pdf response.setHeader("Content-disposition", "attachment; filename="+URLEncoder.encode(name, "UTF-8"));// 设定输出文件头 is = new BufferedInputStream(new FileInputStream(new File(path+name))); out = new BufferedOutputStream(os); byte[] buff = new byte[1024]; int len = 0; while ((len = is.read(buff, 0, buff.length)) != -1) { out.write(buff, 0, len); } out.flush(); } catch (IOException e) { e.printStackTrace(); throw new ServiceException("下载失败"); } finally { IOUtils.closeQuietly(out); IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } return fileDypeVos; }
前段Vue:
/sys/comp/downLoad 接口路径
row 传的id的值进行查询相关路径
token 我们有项目验证看项目情况
window.location.href = `${ipConfig.SERVER_IP}/sys/comp/downLoad?id=${row}&token=${token}`
4.2 下载接口代码 (上面有公共的下面提供Controller与ServiceImpl接口)
控制台代码Controller
/** * 文件预览接口 * @param response * @param id * @param isOnLine * @return */ @RequestMapping(value ="/printFile" ,method = RequestMethod.POST) @ResponseBody public MsgContext printFile(HttpServletResponse response,@RequestParam("id") Long id) { try{ //判断文件是否为空 isEmpty if (id == null){ return MsgContext.createErrorContext("id不能为空"); } MsgContext mc = new MsgContext(); String fInfoVo = dsService.printFile(id); mc.addResult("data", fInfoVo); mc.setMsg("查询成功"); return mc; }catch (Exception e) { return MsgContext.createErrorContext("预览失败,原因=》"+e.getMessage()); } }
Impl代码 采用转换base64的方式
/** * 预览 */ @Override public String printFile(Long id) throws IOException { try { FileDypeVo fileDypeVos = fileMapper.selectFileId(id); String path = fileDypeVos.getFilePath(); String name = fileDypeVos.getFileName(); File file = new File(path+name); FileInputStream inputFile = new FileInputStream(file); byte[] buffer = new byte[(int) file.length()]; inputFile.read(buffer); inputFile.close(); System.out.println(new BASE64Encoder().encode(buffer)); return new BASE64Encoder().encode(buffer); } catch (Exception e) { throw new ServiceException("预览失败" + e.getMessage()); // TODO: handle exception }
前段代码:
npm install --save vue-pdf //下载插件 <pdf :style="{ width: pdfWidth + '%',top:'20px' }" v-for="i in numPages" :key="i" :src="src" :page="i" ref="myPdfComponent"></pdf> import pdf from "vue-pdf"; import CMapReaderFactory from "vue-pdf/src/CMapReaderFactory.js"; components: { pdf, }, previewFile({ id: fileId }).then(res => { if (res.code == 1) { let da = res.result.data this.isShowOk = true let datas = "data:application/pdf;base64," + da; this.src = pdf.createLoadingTask({ url: datas, CMapReaderFactory }); console.log(this.src) this.src.promise.then(pdf => { this.numPages = pdf.numPages; }); } else { this.$message.error(res.msg) } })
前段相关模块;
4.3 Base64转换demo
package com.example.democrud.democurd.controller; import sun.misc.BASE64Encoder; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class TestDemo2 { public static void main(String[] args) throws Exception { String path="G:\\可视化工具\\XXX\\前端\\client05\\public\\file\\FIRSTLY\\a.pdf"; TestDemo2.encodeBase64File(path); } /* *actions: 将文件转成base64 字符串 *path:文件路径 */ public static String encodeBase64File(String path) throws Exception { File file = new File(path); FileInputStream inputFile = new FileInputStream(file); byte[] buffer = new byte[(int) file.length()]; inputFile.read(buffer); inputFile.close(); System.out.println(new BASE64Encoder().encode(buffer)); return new BASE64Encoder().encode(buffer); } /* *actions: 将base64字符保存文本文件 *targetPath:文件路径 *base64Code: base64字符串 */ public void toFile(String base64Code, String targetPath) throws Exception { byte[] buffer = base64Code.getBytes(); FileOutputStream out = new FileOutputStream(targetPath); out.write(buffer); out.close(); } }
5.0 文件删除接口代码 (上面有公共的下面提供Controller与ServiceImpl接口)
@RequestMapping(value ="/delectFile" ,method = RequestMethod.POST) @ResponseBody public MsgContext delectFile(@RequestParam("id") Long id){ try{ //判断文件是否为空 isEmpty if (id == null){ return MsgContext.createErrorContext("请选择需要删除文件,文件不能为空"); } MsgContext mc = new MsgContext(); Long fInfoVo = dsService.delectFile(id); if (fInfoVo>1) { mc.addResult("data", "删除成功"); } return mc; }catch (Exception e) { return MsgContext.createErrorContext("删除失败,原因=》"+e.getMessage()); } }
@Override public Long delectFile(Long id) { if (id==null) { throw new ServiceException("删除id不容许为空"); } FileDypeVo fileDypeVos = fileMapper.selectFileId(id); String path = fileDypeVos.getFilePath(); String name = fileDypeVos.getFileName(); File file = new File(path+name); LOGGER.info("file==>"+file+"|file.exists()==>"+file.exists()); if (!file.exists()) { throw new ServiceException("未在指定路径发现该文件"+file); } boolean lFile=file.delete(); Long le=null; if (lFile) { le=1L; } // TODO Auto-generated method stub return le; }
大家根据自己的业务场景去设计相关接口需求;上面只供参考;有问题或者疑问请提出;
6.0 网上的(四种) Java下载文件的四种方式详细代码
1.以流的方式下载
public HttpServletResponse download(String path, HttpServletResponse response) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return response; }
2.下载本地文件
public void downloadLocal(HttpServletResponse response) throws FileNotFoundException { // 下载本地文件 String fileName = "Operator.doc".toString(); // 文件的默认保存名 // 读到流中 InputStream inStream = new FileInputStream("c:/Operator.doc");// 文件的存放路径 // 设置输出的格式 response.reset(); response.setContentType("bin"); response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // 循环取出流中的数据 byte[] b = new byte[100]; int len; try { while ((len = inStream.read(b)) > 0) response.getOutputStream().write(b, 0, len); inStream.close(); } catch (IOException e) { e.printStackTrace(); } }
3.支持在线打开文件/下载啊的一种方式
public class FileDownloadUtil { /** * 支持在线打开文件的一种方式 * @param filePath * @param response * @param isOnLine * @throws Exception */ public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception { File f = new File(filePath); if (!f.exists()) { response.sendError(404, "File not found!"); return; } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[8192]; int len = 0; response.reset(); // 非常重要 if (isOnLine) { // 在线打开方式 URL u = new URL("file:///" + filePath); response.setContentType(u.openConnection().getContentType()); response.setHeader("Content-Disposition", "inline; filename=" + f.getName()); // 文件名应该编码成UTF-8 } else { // 纯下载方式 response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + f.getName()); } OutputStream out = response.getOutputStream(); while ((len = br.read(buf)) > 0){ out.write(buf, 0, len); } br.close(); out.close(); } }
4.0 网络url下载,并写入浏览器
public class FileDownloadUtil { /** * 网络url下载 * @param request * @param response */ public void downloadFileURL(HttpServletRequest request, HttpServletResponse response) { String fileUrl = "http://oss.aliyun.cn/pro/2021/06/30/2635a51b-3338-478c-9e46-0e7834afabbb.pdf"; try { URL url = new URL(fileUrl); URLConnection conn = url.openConnection(); InputStream inStream = conn.getInputStream(); //对文件名进行编码防止中文乱码 String filename = FileDownloadUtil.encodeDownloadFilename("文件.pdf", request); response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + filename); OutputStream out = response.getOutputStream(); byte[] buffer = new byte[8192]; int length; while ((length = inStream.read(buffer)) != -1) { out.write(buffer, 0, length); } inStream.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } public class FileDownloadUtil { /** * 下载文件时,针对不同浏览器,进行附件名的编码 * * @param filename 载文件名 * @param request 请求request * @return 编码后的下载附件名 * @throws IOException */ public static String encodeDownloadFilename(String filename, HttpServletRequest request) throws IOException { String agent = request.getHeader("user-agent");//获得游览器 if (agent.contains("Firefox")) { // 火狐浏览器 filename = "=?UTF-8?B?" + Base64.getEncoder().encode(filename.getBytes("utf-8")) + "?="; filename = filename.replaceAll("\r\n", ""); } else { // IE及其他浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+"," "); } return filename; } }