echarts在後臺生成圖片的研究及最終解決辦法
我們專案中前端使用echarts圖表來展示資料。近期接到一個新需求,需要在後臺生成分析報告,就是要有固定的許多分析圖表都要在後臺生成,加上語言描述,最終生成word文件提供下載。 顯然,這裡幾十張上百張echarts圖表的生成不能通過開啟瀏覽器通過js來實現了,需要在後臺進行生成。
一、前言
接到需求後,首先想到了是不是可以通過模擬瀏覽器點選開啟網頁的方法,將得到的echarts圖片一一儲存,又想到是不是需要另一臺windows伺服器,寫bat指令碼進行瀏覽器的開啟網頁儲存圖片等的操作......(由於之前沒用過phantomjs這個神器,後邊詳細說明過程,這裡思路是正確的,只是不需要真實的瀏覽器而已)
二、使用nodejs來生成echarts的摸索(可行的方法之一)
這裡看到了nodejs上的相關的元件,包括這個node-echarts元件:https://github.com/suxiaoxin/node-echarts 這裡大家也可以進行嘗試,是通過node-canvas和node-echarts兩個node元件來生成圖片的。只需要將echarts的option屬性給定即可,是可以生成echarts圖表的。
我研究了兩天時間,而我最終由於生成的echarts圖片的中文亂碼問題,發現是canvas不能很好的支援導致的(canvas有支援字型庫匯入的API,但是API似乎沒有釋出),這裡大家可以自己進行嘗試,或者echarts圖中沒有中文的情況,可以用這種方法來實現。(安裝這個node元件需要gcc4.8.5以上,c++11來進行編譯,centos6.X的gcc可能要自己升級一下。node-echarts元件的依賴是以下兩個包,大家也可以分別進行研究)
npm安裝過程中如果遇到問題可以和我進行討論,或者make & make install 過程中有問題也可以進行討論,遇到的問題就不再一一列舉了。
"dependencies": {
"canvas-prebuilt": "^1.6.5-prerelease.1",
"echarts": "^3.6.2"
}
三、最終使用的方案(使用phantomjs來進行“後臺網頁截圖”)
經過nodejs一番折騰後,網上查閱了大量的資料沒有找到合適的答案,最後發現確實可以實現最初的想法,使用phantomjs即可。先搬過來一段介紹:
phantomjs是一個基於webkit核心的無頭瀏覽器。即沒有UI介面的一個瀏覽器,只是其內的點選、翻頁等人為相關操作需要程式設計實現。PhantomJS提供JavaScript API介面,即通過編寫js程式可以直接與webkit核心互動,在此之上可以結合Java語言等,通過Java語言呼叫js等相關操作。(網上phantomJS相關的資料和API很多,大家可以自行查詢用法並嘗試)
簡單的網頁截圖示例:
var page = require('webpage').create();
var address = 'http://baidu.com';//填寫需要列印的HTML檔案
var output = './1.png';//儲存檔案路徑和名稱
page.viewportSize = { width: 1280, height: 800 };//設定長寬
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 500);
}
});
當然也可以擷取頁面的一部分(將page.open函式中進行截圖div區域的選擇即可)
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
length = page.evaluate(function () {
//此函式在目標頁面執行的,上下文環境非本phantomjs,所以不能用到這個js中其他變數
var div = document.getElementById('bar-chart-container'); //要截圖的div的id
var bc = div.getBoundingClientRect();
var top = bc.top;
var left = bc.left;
var width = bc.width;
var height = bc.height;
window.scrollTo(0, 10000);//滾動到底部
return [top, left, width, height];
});
console.log(length);
page.clipRect = { //截圖的偏移和寬高
top: length[0],
left: length[1],
width: length[2],
height: length[3]
};
}, 5000);
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 5000 + 500);
}
});
最終,就得到了phantomJS在後臺截圖得到的echarts圖表了,真實截圖如下:
phantomJS截圖是所見即所得,火狐或者谷歌看到的圖案是怎樣,那麼後臺截圖得到的就是同樣的。需求完成。
四、補充
在phantomJS使用的時候,由於我們web系統是需要登入後使用的,這裡還涉及到了一些phantomJS的cookie自動登入的知識,只需要將cookie的key和value加入phantom指令碼中,就可以實現自動登入,來請求站點下的所有資源了。見博文http://blog.csdn.net/yx0628/article/details/78275714