1. 程式人生 > >echarts在後臺生成圖片的研究及最終解決辦法

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