將營業日報生成圖片下載至用戶手機保存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()
,就基本排除這個問題了