瀏覽器端用JS實現創建和下載圖片

問題場景

在前端很多的項目中,文件下載的需求很常見。尤其是通過JS生成文件內容,然後通過瀏覽器端執行下載的操作。如圖片Execl 等的導出功能。日前,項目中就遇到了這類需求,在瀏覽器端實現保存當前網頁爲圖片,然後還可以下載

解決方案

網頁生成圖片

這裏可以採用 html2canvas 來實現。並且可以兼容大部分主流的瀏覽器。

  • Firefox 3.5+
  • Google Chrome
  • Opera 12+
  • IE9+
  • Safari 6+

文件下載

第一種方案

HTML5 新增了 download 屬性,只要給 download 加上想要導出的文件名即可。如 download="file.jpg"。想要詳細的瞭解此屬性,可以參考 張鑫旭 寫的一篇博文,傳送門

簡單代碼實現如下:

import html2canvas from 'html2canvas';

// 生成圖片,並自動下載
function captureScreenshot() {
  const preview = document.querySelector('.preview-graphs');
  html2canvas(preview).then((canvas) => {
      var img = document.createElement('a');
      img.href = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
      // 下載的文件名字
      img.download = `file.jpg`;
      img.click();
    })  
}

Note:上述實現,目前只有 Google Chrome 功能是正常的。兼容性存在很大的問題

第二種方案

這裏可以採用 FileSaver.js。需以 Blob 的形式來進行保存。canvas 提供了一種創建 Blob 對象,但是兼容性堪憂,絕大部分瀏覽器都沒有實現。因此官網特意提供了這樣的一個庫,canvas-toBlob.js

FileSaver.js is the solution to saving files on the client-side, and is perfect for web apps that generates files on the client, However if the file is coming from the server we recommend you to first try to use Content-Disposition attachment response header as it has more cross-browser compatible. - 摘自官網

FileSaver.js 是在客戶端保存文件的解決方案,非常適合在客戶端生成文件的Web應用程序,但是如果文件來自服務器,我們建議您首先嚐試使用 Content-Disposition 附件響應 標題,因爲它有更多的跨瀏覽器兼容。

可以兼容主流的瀏覽器,如 Firefox,Chrome,Edge,IE 10+ 等。

代碼實現如下:

import html2canvas from 'html2canvas';
import FileSaver from 'file-saver';

// 這裏沒有用 canvas-toBlob.js
// base64 轉換成 Blob
function dataURLToBlob(dataURL) {
  var BASE64_MARKER = ';base64,';
  var parts;
  var contentType;
  var raw;

  if (dataURL.indexOf(BASE64_MARKER) === -1) {
    parts = dataURL.split(',');
    contentType = parts[0].split(':')[1];
    raw = decodeURIComponent(parts[1]);

    return new Blob([raw], {type: contentType});
  }

  parts = dataURL.split(BASE64_MARKER);
  contentType = parts[0].split(':')[1];
  raw = window.atob(parts[1]);
  var rawLength = raw.length;
  var uInt8Array = new Uint8Array(rawLength);

  for (var i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  return new Blob([uInt8Array], {type: contentType});
}

// 生成圖片,並自動下載
function captureScreenshot() {
  const preview = document.querySelector('.preview-graphs');
  html2canvas(preview).then((canvas) => {
     const fileBlob = dataURLToBlob(canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream'));
     const fileName = `file.jpg`;
     FileSaver.saveAs(fileBlob, fileName);
  });  
}

相關鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章