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。这样,我们就可以实现图表下载了。