将营业日报生成图片下载至用户手机保存html
toDataUrl
得到base64格式的图片数据`<a href="base64Url" download="name.jpg"></a>`
复制代码
html2canvas将页面转换为canvas -> canvas转换dataURL -> base64ToBlob(dataUrl转换为2进制文件流) -> new FormData,将blob放置入该表单对象 -> post请求发送至后端保存图片 -> 后端返回图片地址 -> 使用线上地址展现图片 -> 用户长按保存图片vue
// 安装
npm install html2canvas --save
// 引入
import Html2canvas from 'html2canvas';
Vue.prototype.html2canvas = Html2canvas;
// 使用
this.html2canvas(document.querySelector('#id'))
.then((canvas) => {
// todo...
})
复制代码
let dataUrl = canvas.toDataURL('image/jpeg');
复制代码
/**
* base64转blob
* @param {String} code base64个数数据
* @return {undefined}
* @author xxx
*/
base64ToBlob (code) {
let parts = code.split(';base64,');
let contentType = parts[0].split(':')[1];
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new window.Blob([uInt8Array], {type: contentType, name: 'file_' + new Date().getTime() + '.jpg'});
}
let blob = base64ToBlob(dataUrl);
复制代码
// 新建formData
let formData = new FormData();
// 将blob存入
formData.append('file', blob);
复制代码
此处由于使用的是vue,因此用的axios,提交的时候要注意content-type
android
注意:建立请求的时候须要新建axios实例去请求,不要使用import进来的axios,否则content-type修改会不成功ios
import axios from 'axios';
// 建立新的axios实例
let instance = axios.create({});
// 设置content-type为false就好了
instance.defaults.headers.post['Content-Type'] = false;
// 这里特别注意,建立请求的时候,使用这个新建立的实例去进行请求,而不要使用原来的axios
instance({
method: 'POST',
data: formData
})
.then(res => {
// todo...
})
复制代码
这里就不用说什么了,本身建立一个遮罩层去实现就好了git
以上,功能就所有实现,虽然没法实现点击直接下载,可是也在条件容许的范围内,实现比较好的用户体验了github
这个方案在android上面一直测试的比较顺利,可是在ios上面出现过一些疑问web
主要就是canvas.toDataUrl()
这个api失效chrome
当时android顺利调通,在ios上测试的时候,发现js运行到canvas.toDataUrl()
就中止了,没有返回值也没有什么错误提示npm
最后发现是本身添加的水印效果致使在ios执行canvas.toDataUrl()
的时候无响应(canvas画出水印,转换base64,添加到父级backgroung-image的实现方式),改变了水印实现方式就正常运行了canvas
下面把整整一天的踩坑过程写下,给各位参考:
刚开始怀疑html2canvas转化出来的canvas有问题,网上看了不少提问,包括github上面html2canvas的issue,有说多是html2canvas版本问题的,有说多是canvas画出的图片过大,致使canvas.toDataUrl()
在ios上运行被系统强行阻止的各类说法,通过测试,都没法解决如今的问题
虽然最后证明了不是上述的问题,但仍是将测试结果写下
npm默认安装的是"html2canvas": "^1.0.0-alpha.12"
这个alpha版本
随后我测试过最后的正式release版本,v0.4.1
,证明能够正常运行,可是碰到的没法转换超出屏幕部分的dom,和转换的图片模糊的问题要花太多精力去解决,并且做者说了在旧版本有太多的bug,建议使用新的版本,因此最后放弃了旧版本的尝试
canvas.toDataUrl()
在ios上运行被系统强行阻止我转换出来的图片大小在200k左右(用的'image/jpeg'的类型),没查到网上说的这个极限到底在哪里
当时用本身新建的canvas从新压缩了图片,压缩到只有1kb的时候都如法正常运行canvas.toDataUrl()
,就基本排除这个问题了