HighCharts一是款基于SVG的图表工具,用jQuery与SVG交互,具有动画效果,并能实现钻(这个字搞不好写错了)取功能。可能由于HighCharts是收费的,所以图表的下载代码并没有开放,大家一定会发现,只有连接了互联网,才能使用此功能,这在实际的项目中当然是不能用了,因为大部份的企业局域网是不能访问互联网的,那就只好自己来开发这块功能了。
1、首先我们要讲讲SVG,那么什么是SVG呢?
SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG由W3C制定,是一个开放标准。 SVG严格遵从XML语法,并用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式。
SVG在网络上有很多教程,这里我就不详细介绍了,大家可以参考以下链接:http://www.chinasvg.com;
2、我们点击导出图片的时候实际上是吧svg图片数据以post请求的方式发送给了Exports.highcharts.com, 该站 点是以php程序出来这些数据的。
这个是从某位高手那里找来的,老外写的,用java来处理svg 图片数据导出各种图片。
使用的是apache 的batik, 必须下载batik的jar包,
这个包是干嘛的?我现在只知道是用来将svg 图片数据转成各种格式图片的。
DownloadCharAction.java
package com.zh.dy.action.upload; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import javax.servlet.ServletOutputStream; import org.apache.batik.transcoder.SVGAbstractTranscoder; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.JPEGTranscoder; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.fop.svg.PDFTranscoder; import org.apache.struts2.ServletActionContext; import com.zh.dy.action.supers.Action; import com.zh.dy.utils.highcharts.ChartsType; import com.zh.dy.utils.highcharts.FileExtendsName; public class DownloadCharAction extends Action { /** * */ private static final long serialVersionUID = 5377397425073812187L; private String serverPath; private static String pdfFileName; private static String jpgFileName; private static String pngFileName; private static String svgFileName; //private static String serverFolder="/uploads/charts/"; @Override public String execute() throws Exception { serverPath=ServletActionContext.getServletContext().getRealPath("uploadFiles"); File dir = new File(serverPath); // 如果这个目录不存在,则创建它。 if (!dir.exists()) dir.mkdir(); // 创建当前类型文件所在目录 serverPath = serverPath + "\\" + "tj\\"; dir = new File(serverPath); // 如果这个目录不存在,则创建它。 if (!dir.exists()) dir.mkdir(); String fileName = this.getRequest().getParameter("filename"); String svg = this.getRequest().getParameter("svg"); String type = this.getRequest().getParameter("type"); String width = this.getRequest().getParameter("width"); pdfFileName=serverPath+fileName+FileExtendsName.pdf.getGetFileExtendName(); jpgFileName=serverPath+fileName+FileExtendsName.jpg.getGetFileExtendName(); pngFileName=serverPath+fileName+FileExtendsName.png.getGetFileExtendName(); svgFileName=serverPath+fileName+FileExtendsName.svg.getGetFileExtendName(); File file = null; TranscoderInput transInput = new TranscoderInput(); transInput.setReader(new StringReader(svg)); SVGAbstractTranscoder transCoder = null; TranscoderOutput transOutput = null; if (ChartsType.image_png.getChartsTypeName().equalsIgnoreCase(type)) { transCoder = new PNGTranscoder(); file = new File(pngFileName); } if (ChartsType.image_jpeg.getChartsTypeName().equalsIgnoreCase(type)) { transCoder = new JPEGTranscoder(); file = new File(jpgFileName); } if (ChartsType.application_pdf.getChartsTypeName().equalsIgnoreCase(type)) { transCoder = new PDFTranscoder(); file = new File(pdfFileName); } if (ChartsType.image_svg_xml.getChartsTypeName().equalsIgnoreCase(type)) { file = new File(svgFileName); OutputStream output = new FileOutputStream(file); output.write(svg.getBytes()); output.flush(); output.close(); } if (transCoder != null) { transCoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float( width)); OutputStream output = new FileOutputStream(file); transOutput = new TranscoderOutput(output); try { transCoder.transcode(transInput, transOutput); output.flush(); output.close(); } catch (TranscoderException e) { e.printStackTrace(); } } if(file.exists()) { //复位response this.getResponse().reset(); this.getResponse().setContentType(ChartsType.contentType.getChartsTypeName()); this.getResponse().setBufferSize(2048); this.getResponse().setHeader(ChartsType.content_Disposition.getChartsTypeName(), ChartsType.attachment.getChartsTypeName()+file.getName()); this.getResponse().setContentLength(Integer.parseInt(file.length()+"")); InputStream is=new FileInputStream(file); byte[] buf=new byte[2048]; int resultLength=0; ServletOutputStream sos=this.getResponse().getOutputStream(); while((resultLength=is.read(buf))!=-1) { sos.write(buf,0,resultLength); } sos.flush(); sos.close(); this.getResponse().flushBuffer(); } return null; } }
FileExtendsName.java
package com.zh.dy.utils.highcharts; public enum FileExtendsName { svg(".svg"), pdf(".pdf"), png(".png"), jpg(".jpg"); private String getFileExtendName; public String getGetFileExtendName() { return getFileExtendName; } private FileExtendsName(String getFileExtendName) { this.getFileExtendName = getFileExtendName; } }
ChartsType.java
package com.zh.dy.utils.highcharts; public enum ChartsType { image_png("image/png"), image_jpeg("image/jpeg"), application_pdf( "application/pdf"), image_svg_xml("image/svg+xml"),contentType("application/x-download"),content_Disposition("Content-Disposition"),attachment("attachment;filename="); private String chartsTypeName; private ChartsType(String chartsTypeName) { this.chartsTypeName = chartsTypeName; } public String getChartsTypeName() { return chartsTypeName; } public void setChartsTypeName(String chartsTypeName) { this.chartsTypeName = chartsTypeName; } }
修改exporting.js中的服务端url,默认是http://export.highcharts.com/,我们需要改成自己项目中的URL。这样,我们就可以实现图表下载了。