看到上方這張圖片,如果喜歡的話會怎麼儲存呢?
沒錯~就是在圖片上點選右鍵並且選擇「另存圖片」下載它,那該怎麼做?
在 a 連結中即可實現
W3School 的範例程式碼:
1 | <a href="/images/myw3schoolsimage.jpg" download></a> |
只要在 image
資料中的檔案,透過 a
連結,最後加上 download
屬性就可以完成這個功能。
但是今天 PM 跑來說:
「客戶那邊要求在表單下方要有一個按鈕,表單所產生的 data 的資料,按下按鈕可以下載,然後這個檔案要用 excel 打開。」
所以獲得以下資訊:
- 有一個按鈕。
- 會有 data 資料產生。
- 有下載功能。
- 要用 excel 可以打開的格式。
這時馬上請教 Google 大神,然後找到了 Blob,跟想起來好像 excel 匯出有一個叫做 CSV 格式檔案,會用來匯入的。
CSV 逗號分隔值
逗號分隔值(Comma-Separated Values,CSV,有時也稱為字元分隔值,因為分隔字元也可以不是逗號),其檔案以純文字形式儲存表格資料(數字和文字),更多請看維基百科。
Blob
MDN 這樣解釋:
Blob(Binary Large Object)物件代表了一個相當於檔案(原始資料)的不可變物件。Blob 中的資料並不一定是 JavaScript 原生的格式。File 介面基於 Blob,繼承 blob 並擴充其功能以支援操作使用者系統上的檔案。
看一下程式碼:
HTML
1 | <button class="downloadBtn">Download File</button> |
JavaScript
綁定 button
與建立監聽事件 click
,
1 | let downloadBtn = document.querySelector(".downloadBtn"); |
在函式 downloadFile();
寫入要下載的方法:
1 | function downloadFile() { |
先命名一個變數等於下載的檔案名稱。
data 用一個 function 取得。
new Blob 的方法參考 MDN 介紹的
Blob。
var blob = new Blob([typedArray], {type: ‘application/octet-binary’}); // pass a useful mime type here
var url = URL.createObjectURL(blob);接下來命名一個變數,讓其在網頁建立一個 a 連結功能。
在網頁文件的 body 瀏覽器新增一個子節點,其參數為剛剛建立的 a 連結。
a 連結的屬性等於剛剛宣告的 href 變數。
再給 a 連結一個 download 點擊事件等於宣告的文件檔案名稱。
產生點擊事件。
補充:
外部建立click
的監聽事件,是呼叫 function 用,而 function 內的click();
,是針對透過 JS 建立的a
連結所產生的點擊事件,所以兩個是不同的!
假資料
1 | function getRandomData() { |
codepen: https://codepen.io/hnzxewqw/pen/WNQKMKG
用 JS 寫一個載入檔案 load File 功能
有下載檔案,一定也有透過本地端載入檔案到網頁上的功能,在 HTML 5 有建立一個 load 的語法,但會有預設的樣式,
1 | <input type="file" id="myfile" name="myfile" /> |
Codepen https://codepen.io/hnzxewqw/pen/dyYQzOy
但這次專案中是使用 button 按鈕來取得檔案,要有美美的按鈕,所以改寫一下,
1 | <input type="file" id="file" hidden /> |
因為在 input 使用 hidden 屬性,所以原本預設的 input 就會看不見。必須使用 JS 來控制該功能,這邊使用的是 jQuery,
1 | $(".btn_loadFile").click(function () { |
這樣就可以實現檔案下載的功能,又能具備好看的 button。
CodePen https://codepen.io/hnzxewqw/pen/zYvMdoy
註 1.
網際網路媒體類型(Internet media type,也稱為 MIME 類型(MIME type)或內容類型(content type))是給網際網路上傳輸的內容賦予的分類類型。這邊的情境是
application/octet-stream:任意的二進制檔案(通常做為通知瀏覽器下載檔案),還有很多種類型的介紹,請見維基百科。