ブラウザ側はJSで画像の作成とダウンロードを実現する


質問シーン
フロントエンドの多くのプロジェクトでは、ファイルのダウンロードのニーズが一般的です.特にJSでファイルコンテンツを生成し,ブラウザ側でダウンロードを行う.画像、Execlなどのエクスポート機能.先日、プロジェクトでこのようなニーズに遭遇し、ブラウザ側で現在のページを画像として保存し、ダウンロードすることもできます.
ソリューション
Webページの画像生成
ここではhtml 2 canvasを用いて実現できる.ほとんどの主流のブラウザと互換性があります.
  • Firefox 3.5+
  • Google Chrome
  • Opera 12+
  • IE9+
  • Safari 6+

  • ファイルのダウンロード
    第1のシナリオ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機能だけが正常です.互換性に大きな問題があります.
    第2のシナリオ
    ここではFileSaverを採用することができる.js.Blobの形で保存する必要があります.canvasは、Blobオブジェクトを作成する方法canvas.toBlob((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);
      });  
    }

    関連リンク
  • Blob
  • HTMLCanvasElement.toBlob()
  • HTMLCanvasElement.toDataURL()