前端代码:
<!-- 合同附件 --> <div slot="main"> <span class="sh-common-groupTitle">合同附件</span> <template> <div> 选择文件: <input type="file" ref="fileInputRef" @change="selectFile" multiple> <!-- 使用multiple属性,可选择多个文件 --> <br/> <!-- <img v-if="imgUrl" :src="imgUrl" alt="" style="width:54px;height:54px;">--> <el-button v-if="imgUrl" type="primary" @click="uploadFile">上传</el-button> <hr/> </div> </template> <el-row> <el-form ref="projectForm" :model="dataForm" v-loading="loading" :disabled="type === 'view' ? true : false"> <el-col :offset="1" :span="20"> <sh-rms-add-row-table :data.sync="dataForm.wjList" :tableList="wjList"> <template slot="handleBtn"> <el-table-column label="操作" width="80" align="center"> <template slot-scope="scope"> <el-button type="primary" size="mini" @click="downFile(scope.row)" >下载</el-button > <el-button type="primary" size="mini" @click="goPreview(scope.row)" >预览</el-button > <el-button type="primary" size="mini" @click="deleteWjList(scope.$index, scope.row)" >删除</el-button > </template> </el-table-column> </template> </sh-rms-add-row-table> </el-col> </el-form> </el-row> </div>
downFile(row) { var objParam = "?id=" + row.id + "&name=" + row.fileName; //地址后面带的参数,根据自己业务来 window.location.href = 'http://127.0.0.1:30038/api/xcjc/contract/downloadFile' + objParam; },
//预览 goPreview(row) { window.open(`${location.origin}/dev/api/xcjc/contract/download?fileName=` + row.fileName) },
selectFile() { let file = this.$refs['fileInputRef'].files[0] console.log(file) // 上传前, 可以预览该图片 let blobUrl = URL.createObjectURL(file) this.imgUrl = blobUrl },
uploadFile() { // 因为可能选择多个文件, 所以这里是个数组 let file = this.$refs['fileInputRef'].files[0] let formData = new FormData() formData.append('file', file) // 必须和后端的参数名相同。(我们看到了, 其实就是把blob文件给了formData的一个key) formData.append("type", 'avatar') formData.append("id",this.id) axiosInstance({ // 这种传参方式, 在axios的index.d.ts中可以看到 url: '/api/xcjc/contract/upload', method: 'post', data: formData, // 直接将FormData作为data传输 headers: { 'a': 'b' // 可携带自定义响应头 } }).then((res) => { if (res.code == 200) { this.$message({ type: "success", message: res.msg, duration: 1000, onClose: () => { this.refreshList = true; }, }); this.$request({ url: `/api/xcjc/contract/findWjList`, method: "post", data: { sysContractCode: this.dataForm.sysContractCode, }, }).then((res) => { if (res.code == 200) { this.dataForm.wjList = res.data; } else { this.$message({ type: "error", message: res.msg, }); } }) // this.dataForm.wjList = res.data; } else { this.$message({ type: "error", message: res.msg, }); } }) console.log(this.$refs['fileInputRef'].value); // C:\fakepath\cfa86972-07a1-4527-8b8a-1991715ebbfe.png // 上传完文件后, 将value置为空, 以避免下次选择同样的图片而不会触发input file的change事件。 // (注意清空value后,将不能再从input file中获取file,而原先的file仍然能够使用) this.$refs['fileInputRef'].value = '' },
上传后台代码:
controller
/** * @param multipartFile 上传附件 * @return */ @PostMapping("upload") public ActionResult addAttach(@RequestPart("file")MultipartFile multipartFile,@RequestPart("id") String id,@RequestPart("type") String type) throws IOException { String Path = "E:/cjk/现场监管/3hxcjcjg/xcjc-core/src/main/resources/file"; // 获取文件名称 System.out.println(type); String fileName = multipartFile.getOriginalFilename(); // 获取文件的大小 long fileSize = multipartFile.getSize(); String uuid = String.valueOf(UUID.randomUUID()); SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(System.currentTimeMillis()); String format = formatter.format(date); // 获取文件的字节输入流 InputStream inputStream = multipartFile.getInputStream(); multipartFile.transferTo(new File(Path + fileName)); //通过CommonsMultipartFile的方法直接写文件(注意这个时候) Map<String,String> map = new HashMap<String, String>(); UserInfo userInfo = userProvider.get(); String userName = userInfo.getUserName(); map.put("createUser",userName); map.put("id",uuid); map.put("file_name",fileName); map.put("path",Path+fileName); // map.put("size",String.valueOf(fileSize)); map.put("createTime", format);//上传日期 String contentType = multipartFile.getContentType();//文件类型 map.put("type",contentType); //此句查询可以不用,因为我这里关联到其它表,所以要根据id关联 String sysContractCode = jcContractInfoService.selectSystemContractCode(id); map.put("sys_contract_code",sysContractCode); fileService.insertFile(map); // List<String> list = map.keySet().stream().collect(Collectors.toList()); // List<Map> list = new ArrayList<>(); // list.add(map); return ActionResult.success(map); }
serveice:
// 上传文件 Integer insertFile(Map<String,String> map);
serviceImpl:
/** * 文件上传 * @param map * @return */ @Override public Integer insertFile(Map<String,String> map) { return fjMapper.insertfile(map); }
mapper:
String selectSystemContractCode(String id);
mapper.xml:
<insert id="insertfile" parameterType="map"> INSERT INTO xcjc_file_table (id, file_name,path,create_user,create_time,type,sys_contract_code) VALUES (#{id},#{file_name},#{path},#{createUser},#{createTime},#{type},#{sys_contract_code}) </insert>
下载后端代码:
controller:
/** * 附件下载 * @param id * @param response */ @ResponseBody @GetMapping("downloadFile") public void getSdgsTree (@RequestParam(required = false,value = "id") String id,@RequestParam(required = false,value = "name") String name,HttpServletResponse response){ Map map = new HashMap(); map.put("id",id); map.put("name",name); fileService.downloadFile(map,response); }
service:
//文件下载 void downloadFile(Map map, HttpServletResponse response);
serviceImpl:
/** * 附件下载 * @param map * @param response */ @Override public void downloadFile(Map map, HttpServletResponse response) { try { String PATH = "E:/cjk/sdxcjg/3hxcjcjg/xcjc-core/src/main/resources/file/"; String basePath = PATH; // 1、定义输入流,通过输入流读取文件内容 FileInputStream fileInputStream = new FileInputStream(new File(basePath + map.get("name"))); // 2、通过response对象,获取到输出流 ServletOutputStream outputStream = response.getOutputStream(); // 3、通过response对象设置响应数据格式(image/jpeg) response.setContentType(String.valueOf(map.get("type"))+";charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(String.valueOf(map.get("name")), "utf-8")); int len = 0; byte[] bytes = new byte[102400]; while ((len = fileInputStream.read(bytes)) != -1){ // 4、通过输入流读取文件数据,然后通过上述的输出流写回浏览器 outputStream.write(bytes,0,len); // 刷新 outputStream.flush(); } // 5、关闭资源 outputStream.close(); fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } }
后台文件预览:
/** * 附件预览 * **/ @GetMapping(value = "download") public void download(HttpServletResponse res, HttpServletResponse response,String fileName) throws Exception { // String fileName = "2.jpg"; String path = "E:/cjk/现场监管/3hxcjcjg/xcjc-core/src/main/resources/file"+fileName; // String path = "E:/cjk/sdxcjg/3hxcjcjg/xcjc-core/src/main/resources/file/"+fileName; // 把二进制流放入到响应体中 File file = new File(path); if (file.exists()) { byte[] data = null; FileInputStream input = new FileInputStream(file); data = new byte[input.available()]; input.read(data); // 根据文件类型,设置文件Content-Type String fileType = fileName.substring(fileName.lastIndexOf(".")).toUpperCase(); // 设置Content-Type头 switch (fileType) { case ".JPG": response.setContentType("image/jpeg"); break; case ".JPEG": response.setContentType("image/jpeg"); break; case ".PNG": response.setContentType("image/png"); break; case ".PDF": response.setContentType("application/pdf"); break; case ".DOC": response.setContentType("application/msword"); break; case ".txt": case ".DOCX": case ".docx": // case ".docx": // response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); // break; default: response.setContentType("application/json"); } response.getOutputStream().write(data); input.close(); } }