基於one2team架構的Highcharts圖表圖片匯出方案

來源:互聯網
上載者:User

      這篇文章已經沒有什麼意義了,新版的HIghcharts提供Java圖片匯出解決方案,你需要做的就是下個Maven,bulid一個war就Ok了。---addedy on 2012-11-15

     多說一句廢話:我覺得這個功能其實對於大多數應用情境來說是多餘的。

       Highcharts是一個純JSWeb圖表繪製解決方案,它的功能之豐富,使用之簡單可能是目前開源領域排名比較考前的優秀解決方案,它對個人使用是免費的。

      它的預設版本也有圖片匯出功能,不過匯出伺服器是Highcharts官方伺服器,我開發的過程試了一下,好像特別慢,圖片匯出服務用自己的對商業使用者來說也有“便利之處”。

       官方的下載頁面推薦的Java圖片匯出方案是one2team/highcharts-serverside-export,這個方案是基於apache的batik包的,也有人直接採用batik包開發了圖片匯出Servlet代碼 (這個代碼沒好像沒有解決中文問題)。我是比較軸的那種人,本來one2team和上面這個代碼核心是一樣,我還是研究了一下怎麼使用這個官方推薦的匯出架構。說實話,官方推薦的這個架構不是很好用,它採用JDK6的泛型特性,項目的編譯器相容性必須提高到1.6,否則編譯會出錯。其次這個架構的主HighchartsExporter類的功能是轉換以Json資料或者Java語言對象為資料來源的匯出功能,而Highchart匯出伺服器是要轉換Highchart圖表post的SVG資料。所以需要對One2Team的架構稍加改造才能使用。One2team的架構的OO設計比較複雜,我就不畫具體的UML圖了。只列出需要引進的幾個類:

      首先繼承SVGRendererInternal抽象類別,重寫callJavascript方法,這個方法的實際作用是把其他格式的資料來源轉換成SVG資料,我不是很明白為什麼SVG資料產生非要在Java裡面調用JavaScript來做,難道為了和瀏覽器的高度一致?,這個地方我們直接返回chartoption即可,這個chartoption在SVG來源資料匯出情況下就是SVG資料本書,所以無需處理,直接返回即可。

/** *  */package org.one2team.highcharts.server.export.util;import org.mozilla.javascript.ScriptableObject;import org.one2team.highcharts.server.export.util.SVGRendererInternal;import org.one2team.highcharts.shared.ChartOptions;/** * @author Dipolar * */public class SVGRendererInternalSVG extends SVGRendererInternal<String> {@Overrideprotected Object callJavascript (final String generalOptions, final String chartOptions) {//return ScriptableObject.callMethod (null, SCRIPTABLE, "renderSVGFromObject",  new Object [] {'(' + generalOptions + ')', chartOptions});return chartOptions;}}

      本來加這麼一個類,匯出圖片就夠了,我為了方便Servlet操作,我又模仿HighchartsExporter類重寫了一個HttpHighchartsExporter類,代碼如下:上面這兩個類都放在了one2team的包類,因為涉及到的一些類是protected的,為了不改寫人家的代碼,所以只好放在人家的包裡了。還有代碼中的globalOptions參數可以省略不計,直接賦null即可,因為這個參數在實際轉換中並沒有用,實際轉換中的globalOptions用的是一個架構本身預定義的常量。

package org.one2team.highcharts.server.export;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.OutputStream;import org.apache.commons.io.IOUtils;import org.one2team.highcharts.server.export.ExportType;import org.one2team.highcharts.server.export.util.*;public class HttpHighchartsExporter<T> {public HttpHighchartsExporter(ExportType type, SVGRendererInternal<T> internalRenderer) {this.type = type;this.renderer = new SVGStreamRenderer<T> (new SVGRenderer<T> (internalRenderer),                     type.getTranscoder ());}public HttpHighchartsExporter(ExportType type) {SVGRendererInternal svgRender=new SVGRendererInternalSVG();this.type = type;this.renderer = new SVGStreamRenderer<T> (new SVGRenderer<T> (svgRender),                     type.getTranscoder ());}public void export (T chartOptions,                T globalOptions,                OutputStream out) {OutputStream fos = null;try {fos = render (chartOptions, globalOptions, out);} catch (Exception e) {e.printStackTrace ();throw (new RuntimeException (e));} finally {if (fos != null)IOUtils.closeQuietly (fos);}}private OutputStream render (T chartOptions,                         T globalOptions,                               OutputStream out) throws FileNotFoundException {renderer.setChartOptions (chartOptions)    .setGlobalOptions (globalOptions)    .setOutputStream (out)    .render ();return out;}public SVGStreamRenderer<T> getRenderer () {return renderer;}public ExportType getType () {return type;}private final SVGStreamRenderer<T> renderer;private final ExportType type;}

     下面來一下真正的Servlet的 doPost的代碼,這個代碼雖然解決了jpg和png的中文亂碼問題,但是沒有解決SVG的匯出的中文亂碼問題,SVG匯出採用svg2svgTranscoder的話,在架構內部的字型調用上出bug了,直接輸出svg,不加OutputStreamWriter封裝的情況下,chrome可以正常開啟這個xml檔案,但是中文是亂碼),IE8下在中文位置出問題,加了OutputStreamWriter封裝器以後,Chrome片可以正常渲染但是報某元素屬性值有問題,IE下報了另外一個錯誤。PDF的匯出需要擴充下一下ExportType枚舉,PDFTranscoder類也不在batik的包裡在apache的fop項目裡面,我嘗試了一下報出Java堆空間不夠的錯誤,我的生產伺服器資源也有限,PDF匯出功能就省略把。

public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { try{ request.setCharacterEncoding("utf-8");//這一行解決了PNG、JPG的中文亂碼問題。 String filename=request.getParameter("filename"); String type=request.getParameter("type"); type=type.replace("svg+", ""); MimeType mtype=new MimeType(type); response.addHeader("Content-Disposition", "attachment; filename="+ filename + "."+mtype.getSubType()); response.addHeader("Content-Type", mtype.getBaseType()+"; charset=UTF-8"); ServletOutputStream out=response.getOutputStream(); String svg=request.getParameter("svg"); if (mtype.getSubType().equals("xml")){ //OutputStreamWriter writer = new OutputStreamWriter(out, "utf-8"); //writer.write(svg); }else{ HttpHighchartsExporter<String> httpExporter = new HttpHighchartsExporter<String> (Enum.valueOf(ExportType.class,mtype.getSubType())); httpExporter.export(svg,null,out);  } out.flush(); out.close(); }catch(Exception e){ e.printStackTrace(); }}

         結語:最後提示一下one2team雖然在做圖片匯出並不一定好,但是JSM系列類可以用來很方便地為前端組建圖表繪製所需要的Json資料,當然這個Json資料可以你自己硬代碼產生Json資料,但是既然有了與HighChart對象一一對象的Java類,為什麼不用一下哪?

     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.