2012-09-24 124 views
1

DOJO开发的项目中有一项新要求,即用户可以将图表导出为PNG图像。我有一个研究,发现2个想法:如何将dojox.charting.Chart转换为用户导出的PNG图像?

1,尝试在DOJO API中找到适当的方法直接导出到PNG图像(因为我与Ext JS相似,它提供了用于导出到图像的API方法),但DOJO图表没有办法做到这一点。

使用像dojox.fx或dojox.gfx这样的DOJO API来绘制图像,但这些不能生成图像。所以我就这样放弃了。

2,使用第三方插件来做到这一点。首先,我可以通过方法'dojox.gfx.utils.toSvg(chart.surface).then'获取图表的表面内容,然后使用Apache的插件Batik将SVG内容转换为PNG图像。以下是我试图代码:

dojox.gfx.utils.toSvg(chart.surface).then(function(svg) { 
    var args = { 
     url : "chart/doExportChart.action", 
     content : { 
      svgContent : svg 
     }, 
     handleAs : "json", 
     load : function(response) { 
      // Do something like exporting the responded image. 
     }, 
     error : function(error) { 
      // Error handling 
     } 
    }; 

    dojo.xhrPost(args); 
    }, 
    function(error) { 
     // Error handling 
    } 
); 

而且方法doExportChart这样做:如下SVG sample.svg的

JPEGTranscoder t = new JPEGTranscoder(); 

// Set the transcoding hints. 
t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8)); 

// Create the transcoder input. 
String svgURI = new File("c:/sample.svg").toURL().toString(); 
TranscoderInput input = new TranscoderInput(svgURI); 

// Create the transcoder output. 
OutputStream ostream = new FileOutputStream("c:/sample.jpg"); 
TranscoderOutput output = new TranscoderOutput(ostream); 

// Save the image. 
t.transcode(input, output); 

// Flush and close the stream. 
ostream.flush(); 
ostream.close(); 

内容:

svg xmlns=httpwww.w3.org2000svg width=1200 height=589defsrect fill=rgb(255, 255, 255) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=41.5 y=13.666666666666666 width=1142 height=528.5 fill-rule=evenoddg transform=matrix(1.00000000,0.00000000,0.00000000,0.00000000,0.00000000,541.16666667)gpolyline fill=none fill-opacity=0 stroke=rgb(204, 204, 204) stroke-opacity=1 stroke-width=1.7 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 points=42.50000000 14.66666667 90.00000000 242.63573883 137.50000000 191.97594502 185.00000000 126.84192440 232.50000000 242.63573883 280.00000000 201.02233677 327.50000000 159.40893471 375.00000000 541.16666667 422.50000000 343.95532646 470.00000000 220.92439863 517.50000000 146.74398625 565.00000000 224.54295533 612.50000000 240.82646048 660.00000000 110.55841924 707.50000000 249.87285223 755.00000000 161.21821306 802.50000000 195.59450172 850.00000000 320.43470790 897.50000000 318.62542955 945.00000000 282.43986254 992.50000000 286.05841924 1040.00000000 349.38316151 1087.50000000 210.06872852 1135.00000000 286.05841924 1182.50000000 329.48109966 stroke-dasharray=none polyline fill=none fill-opacity=0 stroke=rgb(191, 19, 19) stroke-opacity=1 stroke-width=1.5 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 points=42.50000000 14.66666667 90.00000000 242.63573883 137.50000000 191.97594502 185.00000000 126.84192440 232.50000000 242.63573883 280.00000000 201.02233677 327.50000000 159.40893471 375.00000000 541.16666667 422.50000000 343.95532646 470.00000000 220.92439863 517.50000000 146.74398625 565.00000000 224.54295533 612.50000000 240.82646048 660.00000000 110.55841924 707.50000000 249.87285223 755.00000000 161.21821306 802.50000000 195.59450172 850.00000000 320.43470790 897.50000000 318.62542955 945.00000000 282.43986254 992.50000000 286.05841924 1040.00000000 349.38316151 1087.50000000 210.06872852 1135.00000000 286.05841924 1182.50000000 329.48109966 stroke-dasharray=none ggrect fill=rgb(255, 255, 255) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=0 y=0 width=42.5 height=590 fill-rule=evenoddrect fill=rgb(255, 255, 255) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=1182.5 y=0 width=18.5 height=591 fill-rule=evenoddrect fill=rgb(255, 255, 255) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=0 y=0 width=1201 height=14.666666666666666 fill-rule=evenoddrect fill=rgb(255, 255, 255) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=0 y=541.1666666666666 width=1201 height=49.83333333333333 fill-rule=evenoddgline fill=none fill-opacity=0 stroke=rgb(51, 51, 51) stroke-opacity=1 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x1=42.5 y1=541.1666666666666 x2=1182.5 y2=541.1666666666666 stroke-dasharray=none ggline fill=none fill-opacity=0 stroke=rgb(51, 51, 51) stroke-opacity=1 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x1=42.5 y1=541.1666666666666 x2=42.5 y2=14.666666666666666 stroke-dasharray=none line fill=none fill-opacity=0 stroke=rgb(102, 102, 102) stroke-opacity=1 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x1=42.5 y1=427.1821305841924 x2=36.5 y2=427.1821305841924 stroke-dasharray=none text fill=rgb(51, 51, 51) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=32.5 y=430.91546391752576 text-anchor=end text-decoration=none rotate=0 kerning=auto text-rendering=optimizeLegibility font-style=normal font-variant=normal font-weight=normal font-size=7pt font-family=Tahoma fill-rule=evenodd100textline fill=none fill-opacity=0 stroke=rgb(102, 102, 102) stroke-opacity=1 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x1=42.5 y1=246.25429553264598 x2=36.5 y2=246.25429553264598 stroke-dasharray=none text fill=rgb(51, 51, 51) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=32.5 y=249.9876288659793 text-anchor=end text-decoration=none rotate=0 kerning=auto text-rendering=optimizeLegibility font-style=normal font-variant=normal font-weight=normal font-size=7pt font-family=Tahoma fill-rule=evenodd200textline fill=none fill-opacity=0 stroke=rgb(102, 102, 102) stroke-opacity=1 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x1=42.5 y1=65.32646048109962 x2=36.5 y2=65.32646048109962 stroke-dasharray=none text fill=rgb(51, 51, 51) fill-opacity=1 stroke=none stroke-opacity=0 stroke-width=1 stroke-linecap=butt stroke-linejoin=miter stroke-miterlimit=4 x=32.5 y=69.05979381443295 text-anchor=end text-decoration=none rotate=0 kerning=auto text-rendering=optimizeLegibility font-style=normal font-variant=normal font-weight=normal font-size=7pt font-family=Tahoma fill-rule=evenodd300textgsvg 

然后运行上面的代码错误遇到:

Exception in thread "main" org.apache.batik.transcoder.TranscoderException: null 
Enclosed Exception: 
Content is not allowed in prolog. 
    at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:136) 
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:156) 
    at com.ibm.crl.poc.util.PocImageUtil.main(PocImageUtil.java:142) 

我做第二种解决方案遵循http://xmlgraphics.apache.org/batik/using/transcoder.html的官方示例。我不知道并希望有谁给我指导。非常感谢。

回答

0

如果您的意图是支持旧版浏览器,那么使用svg根本就不是一种选择。尽管2006年以前的大多数浏览器版本都有一些基本的支持,但对于Internet Explorer而言,IE8和更旧版本的浏览器需要插件才能呈现SVG内容。

@ Batik异常;它看起来像一个外部源解析失败(有错误来搜索这个问题和样式的语法)。它很难阻止任何在上面的onliner,但尝试下载xmlns并将其放在与sample.svg相同的域中(或试试忽略掉)proposed here

也许这种方法稍微关闭,除非您需要图像具有相同的外观和感觉。你可以使用该系列,用于图表,而不是SVG转换,创建通过JFreeChart或类似的图。

无论哪种方式,你不能指望JavaScript来生成PNG,相关的算法都... encoumbersome :)

最后一个选项存在,是让您的图表呈现在一个框架,使页面非常简单,快速呈现(创建dojolayer以避免100多个请求)。然后,一旦客户端请求图像导出,从服务器端抓取该帧的“快照”。这将确保对SVG的支持存在并给出序列化结果。作为例子:

客户方:

<iframe 
    width=700 
    height=400 
    src="chart/doRenderChart.action?unid=howto_identify_graph"></iframe> 

服务器端,一旦用户点击 '出口':

doExportAction(HttpServletRequest req, HttpServletResponse resp) throws IOException { 
    String chart = req.getParameter('url') 
     = "chart/doRenderChart.action?unid=howto_identify_graph"; 
    int width = 700; 
    int height = 400; 
    File f = File.createTempFile("prefix",null,myDir); 
    String tmpfile = f.getName(); 
    f.delete(); 
    Process p=Runtime.getRuntime().exec("/path/to/bin/wkhtmltoimage "+ 
     "--crop-h " + height + 
     " --crop-w " + height + " " + 
      chart + 
     " -f png " + 
      tmpfile 
    ); 
    p.waitFor(); 
    // get and serve 'tmpfile' contents 
} 

下面是WKHtmlToXX

项目
相关问题