SperingBoot+vue文件上傳下載預覽

上傳文件:
前端:
  • 整個過程,就是在使用FormData 添加 上File(這個Blob),并且key要和后臺的名字對應上
  • 在點擊上傳按鈕開始上傳之前,使用了URL.createObjectURL(File)創建blobUrl,給了img標簽作圖片預覽
  • 上傳完畢后,將input file的value置為空。若將input file置為空,則此時不能再從input file中獲取file了,得等下次再選擇圖片才能獲得file,將它置為空的目的是為了下次選擇同樣的圖片,也能觸發input file的change事件
后端:
  • 后臺僅僅就是用MultipartFile聲明接收即可,可以使用@RequestParam注解 或 @RequestPart注解
  • 調用MultipartFile#transferTo保存文件
  • 可以從MultipartFile#getInputStream中獲取流,比如上傳到OSS。
?前端代碼:
<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><script>
import axiosInstance from '@/utils/request.js'
import axios from 'axios'
export default {name: 'File',data() {return {imgUrl:''}},methods: {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('mfile', file) // 必須和后端的參數名相同。(我們看到了, 其實就是把blob文件給了formData的一個key)formData.append("type", 'avatar')// 可以有下面2種方式, 來上傳文件/* axiosInstance.post('http://127.0.0.1:8083/file/uploadFile',formData, {headers: {'a':'b'}}).then(res => {console.log('響應回來: ',res);}) */axiosInstance({ // 這種傳參方式, 在axios的index.d.ts中可以看到url:'http://127.0.0.1:8083/file/uploadFile',method:'post',data: formData, // 直接將FormData作為data傳輸headers: {'a':'b' // 可攜帶自定義響應頭}}).then(res => {console.log('響應回來: ',res);})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 = ''}}
}
</script><style></style>
后端代碼:
@PostMapping("uploadFile")
public Object uploadFile(@RequestPart("mfile")MultipartFile multipartFile,@RequestPart("type") String type) throws IOException {System.out.println(multipartFile.getClass());System.out.println(type);// 源文件名String originalFilename = multipartFile.getOriginalFilename();// 內容類型String contentType = multipartFile.getContentType();// 文件是否為空(無內容)boolean empty = multipartFile.isEmpty();// 文件大小long size = multipartFile.getSize();// 文件的字節數據byte[] bytes = multipartFile.getBytes();// 獲取文件的字節輸入流InputStream inputStream = multipartFile.getInputStream();// 將文件保存到指定路徑下multipartFile.transferTo(new File("d:/Projects/practice/test-springboot/src/main/resources/file/" + originalFilename));System.out.println(originalFilename);System.out.println(contentType);System.out.println(empty);System.out.println(size);System.out.println(bytes.length);HashMap<String, Object> data = new HashMap<>();data.put("data", "ok");return data;
}
動態a標簽下載
前端代碼
  • 只需要動態創建a標簽,添加到body,然后手動調用js觸發a標簽的click事件,觸發下載
  • 下載完成之后,將a標簽移除
  • 整個過程a標簽的樣式都是display:none
<template><div><el-button type="success" @click="downloadFile">下載文件</el-button></div>
</template><script>
import axiosInstance from '@/utils/request.js'
import axios from 'axios'
export default {name: 'File',data() {return {}},methods: {downloadFile() {let a = document.createElement('a')a.href = 'http://127.0.0.1:8083/file/downloadFile?filename=頭像a.png'document.body.appendChild(a)a.style.display = 'none'a.click()document.body.removeChild(a)}}
}
</script><style></style>
后端代碼:
@GetMapping("downloadFile")
public void downloadFile(@RequestParam("filename") String filename) throws Exception {// 告知瀏覽器這是一個字節流,瀏覽器處理字節流的默認方式就是下載// 意思是未知的應用程序文件,瀏覽器一般不會自動執行或詢問執行。瀏覽器會像對待,// 設置了HTTP頭Content-Disposition值為attachment的文件一樣來對待這類文件,即瀏覽器會觸發下載行為response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);// ,該響應頭指示回復的內容該以何種形式展示,是以內聯的形式(即網頁或者網頁的一部分),還是以附件的形式下載并保存到本地。response.setHeader(HttpHeaders.CONTENT_DISPOSITION,"attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));File file = new File("d:/Projects/practice/test-springboot/src/main/resources/file/" + filename);ServletOutputStream ros = response.getOutputStream();FileInputStream fis = new FileInputStream(file);byte[] bytes = new byte[2 * 1024];int len = 0;while ((len = fis.read(bytes)) != -1) {ros.write(bytes, 0, len);}ros.flush();ros.close();fis.close()}
預覽文件:
前端代碼:
<template><div><a href="http://127.0.0.1:8083/file/previewFile?filename=頭像a.png">頭像a.png</a></div>
</template><script>
import axios from 'axios'
export default {name: 'File',data() {return {}},methods: {}
}
</script><style></style>
后端代碼:
@GetMapping("previewFile")public void previewFile(@RequestParam("filename") String filename) throws Exception {// 可使用ServletContext 通過文件名獲取 媒體資源類型response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE);File file = new File("d:/Projects/practice/test-springboot/src/main/resources/file/" + filename);ServletOutputStream ros = response.getOutputStream();// 可參考: StreamUtilsFileInputStream fis = new FileInputStream(file);byte[] bytes = new byte[4 * 1024];int len = 0;while ((len = fis.read(bytes)) != -1) {ros.write(bytes, 0, len);}ros.flush();ros.close();fis.close()
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538994.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538994.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538994.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

keepalived腦裂問題查找

在自己環境做keepalivedredis實驗時&#xff0c;當重啟了備用redies機器后&#xff0c;發現兩臺redies主機都拿到了VIP [plain] view plaincopy [rootredis2 ~]# ip addr list 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopbac…

python 多線程并行 矩陣乘法_python實現簡單的并行矩陣乘法

python實現簡單的并行矩陣乘法python實現簡單的并行矩陣乘法本文采用的矩陣乘法方式是利用一個矩陣的行和二個矩陣的列相乘時不會互相影響。假設A(m,n)表示矩陣的m行&#xff0c;n列。那么C(m,m)A(m,n) * B(n,m) &#xff1a;計算C矩陣時候分解成&#xff1a;process-1&#xf…

停止Java線程,小心interrupt()方法

轉自http://www.blogjava.NET/jinfeng_wang/archive/2008/04/27/196477.html ---------------------------------------------------------------------------------------------------- 程序是很簡易的。然而&#xff0c;在編程人員面前&#xff0c;多線程呈現出了一組新的難…

python輸入數學表達式并求值_用Python3實現表達式求值

一、題目描述 請用 python3編寫一個計算器的控制臺程序&#xff0c;支持加減乘除、乘方、括號、小數點&#xff0c;運算符優先級為括號>乘方>乘除>加減&#xff0c;同級別運算按照從左向右的順序計算。 二、輸入描述 數字包括"0123456789"&#xff0c;小數點…

mac上的mysql管理工具sequel pro

https://blog.csdn.net/wan_zaiyunduan/article/details/54909389 以前用過Plsql、Navicat、Workbench&#xff0c;現在換到mac上&#xff0c;用了現在這一款管理工具&#xff0c;很好用&#xff0c;所以推薦給大家。 完整的MySQL支持 Sequel Pro是一個快速,易于使用的Mac數據庫…

報錯 classes 拒絕訪問_3種方式“移除”快速訪問;為什么移除?你懂的...

Windows 10 在文件資源管理器中引入了"快速訪問"這個功能&#xff0c;每當打開文件資源管理器窗口時&#xff0c;您都會看到常用文件夾和最近訪問的文件的列表&#xff0c;這個功能雖然方便了日常使用&#xff0c;可能會提高工作效率&#xff0c;但是如果是公司的電腦…

java set是重復_java算法題,set內出現重復元素

題目將數字 1…9 填入一個33 的九宮格中&#xff0c;使得格子中每一橫行和的值全部相等&#xff0c;每一豎列和的值全部相等。請你計算有多少種填數字的方案。這個是計蒜客上面的一個模擬題&#xff0c;我采用暴力。public class _3 {/** 將數字 1…9 填入一個33 的九宮格中&am…

Lock的lockInterruptibly()

概述 lockInterruptibly()方法比較特殊&#xff0c;當通過這個方法去獲取鎖時&#xff0c;如果其他線程正在等待獲取鎖&#xff0c;則這個線程能夠響應中斷&#xff0c;即中斷線程的等待狀態。也就使說&#xff0c;當兩個線程同時通過lock.lockInterruptibly()想獲取某個鎖時&…

python中把輸出結果寫到一個文件中_Python3.6筆記之將程序運行結果輸出到文件的方法...

Python3.6筆記之將程序運行結果輸出到文件的方法 更新時間&#xff1a;2018年04月22日 14:27:32 投稿&#xff1a;jingxian 下面小編就為大家分享一篇Python3.6筆記之將程序運行結果輸出到文件的方法&#xff0c;具有很好的參考價值&#xff0c;希望對大家有所幫助。一起跟隨小…

hangfire.mysql.core_abp 使用 hangfire結合mysql

abp 官方使用的hangfire 默認使用的是sqlserver的存儲mysql須要引入支持mysql的類庫sql我這邊使用的是Hangfire.MySql.Core數據庫直接用nuget安裝便可app首先按照官方文檔要求&#xff0c;改幾個地方sqlserver分別是 Startup 文件下serverservices.AddHangfire(config >{con…

python 圖標題上移_Python-Matplotlib將圖形標題移動到y軸

我目前在python中使用matplotlib來繪制一些數據,但是我希望圖表的標題位于Y軸上,因為沒有足夠的空間來存儲一個圖形的標題和另一個圖形的x軸標簽.我知道我可以將hspace設置為更大的數字但是,我不想這樣做,因為我計劃將幾個圖表堆疊在一起,如果我調整hspace,那么圖表將是真的簡短…

solr的基礎使用

查詢運算符 例如&#xff1a;http://localhost:8984/solr/mycore/select?q*:* : 指定字段查指定值&#xff0c;如返回所有值q*:* ? 匹配單個字符&#xff0c; 例如: qtitle:??拳 可以匹配標題為“形意拳”的文檔 * 匹配零個或多個字符, 例如: qtitle:*形意拳 或者 qtitl…

同步關鍵詞lock

概述 1、API在JDK的java.util.concurrent.locks下。 2、不是Java關鍵字&#xff0c;是接口。 3、ReentrantLock是JDK唯一實現了Lock接口的類。 public interface Lock {//獲取鎖void lock();//可以響應中斷的鎖void lockInterruptibly() throws InterruptedException;//嘗試…

Java bitset轉string_將java BitSet保存到DB

默認情況下,JPA使用Java序列化來保存未知Serializable類型的屬性(以便將序列化表示存儲為byte []).通常它不是您想要的,因為可以有更有效的方式來表示您的數據.例如,BitSet可以有效地表示為數字(如果它的大小有界),或者byte [],或其他東西(遺憾的是,BitSet不提供進行這些轉換的…

python讀取raw圖片文件_在python下讀取并展示raw格式的圖片實例

raw文件可能有些人沒有&#xff0c;因此&#xff0c;先用一張圖片創建一個raw格式的文件&#xff08;其實可以是其他類型的格式文件&#xff09; import numpy as np import cv2 img cv2.imread(cat.jpg) # 這里需要我們在當前目錄下放一張名為cat.jpg的文件 img.tofile(cat.r…

python怎么網絡通信_深入Python中的網絡通信

TCP/IP計算機與網絡設備兩情侶要談戀愛&#xff0c;相互通信&#xff0c;那么雙方就必須有規則。基于相同的方法&#xff0c;不同的硬件、操作系統之間的通信&#xff0c;都需要一種規則。而我們就把這種規則稱為協議(protocol)。TCP/IP 是互聯網相關各類協議族的總稱。TCP/IP是…

ReadWriteLock讀寫文件

概述 ReadWriteLock是一個接口&#xff0c;在它里面只定義了兩個方法&#xff1a;一個讀的鎖和一個寫的鎖。 讀的鎖&#xff1a;A線程獲取了讀的鎖&#xff0c;那么B線程也可以獲取讀的鎖。 寫的鎖&#xff1a;A線程獲取了寫的鎖&#xff0c;那么B線程不能獲取讀也不能獲取寫…

搞懂 Java HashMap 源碼

HashMap 源碼分析 前幾篇分析了 ArrayList &#xff0c; LinkedList &#xff0c;Vector &#xff0c;Stack List 集合的源碼&#xff0c;Java 容器除了包含 List 集合外還包含著 Set 和 Map 兩個重要的集合類型。而 HashMap 則是最具有代表性的&#xff0c;也是我們最常使用到…

python 怎么表示sqlserver null_如何使用Python將sqlserver查詢輸出寫入.txt文件?

我是Python新手&#xff0c;嘗試連接到sqlserverdb并將查詢的輸出轉換成一個flat.txt文件。在一些代碼正在工作&#xff0c;但是只寫了將近1000條記錄&#xff0c;然后就停止了。在Python版本&#xff1a;2.7.13。在下面的代碼能夠把100萬條記錄全部寫入csv文件而不是.txt文件&…

python中object是什么類型_Python 的 type 和 object 之間是怎么一種關系?

class&#xff0c;metaclass&#xff0c;instance&#xff0c;subclass&#xff0c;base 以下成立&#xff1a; 對任意的A&#xff0c;A是instance&#xff08;推論&#xff1a;任意class也是instance&#xff09; 對任意A&#xff0c;存在B&#xff0c;使得B是A的class A是cla…