浏览器端用JS实现创建和下载图片

时间:2023-01-02 02:33:03

问题场景

在前端很多的项目中,文件下载的需求很常见。尤其是通过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((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);
});
}

相关链接

来源:https://segmentfault.com/a/1190000017927051