这篇文章已经没有什么意义了,新版的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> {
@Override
protected 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类,为什么不用一下哪?

基于one2team框架的Highcharts图表图片导出方案的更多相关文章

  1. 基于ssh框架的highcharts前后台数据交互实例

    Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习.个人网站和非商业用途使用.HighCh ...

  2. Highcharts结合PhantomJS在服务端生成高质量的图表图片

    项目背景 最近忙着给部门开发一套交互式的报表系统,来替换原有的静态报表系统. 老系统是基于dotnetCHARTING开发的,dotnetCHARTING的优势是图表类型丰富,接口调用简单,使用时只需 ...

  3. 在asp.net中如何自己编写highcharts图表导出到自己的服务器上来

    1.准备工作:网上下载highcharts导出的关键dll.      1).Svg.dll:因为highcharts的格式其实就是一个xml,采用svg的方式画图:      2).itextsha ...

  4. highCharts图表入门简介

    一.Highcharts简介 Highcharts:功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库 Highcharts是一款纯javascript编写的图表库,能够很简单便捷的在W ...

  5. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续2篇-模板导出综合示例)

    自ExcelUtility类推出以来,经过项目中的实际使用与不断完善,现在又做了许多的优化并增加了许多的功能,本篇不再讲述原理,直接贴出示例代码以及相关的模板.结果图,以便大家快速掌握,另外这些示例说 ...

  6. 基于ADB框架Robotium跨进程操作

    转自:http://blog.csdn.net/qingchunjun/article/details/42580937 2015年2月3日更新: 有些朋友在用真机尝试本方法时,抛出了InputStr ...

  7. rtvue-lowcode:一款基于uniapp框架和uview组件库的开源低代码开发平台

    rtvue-lowcode低代码开发平台 rtvue-lowcode一款基于uniapp框架和uview组件库的低代码开发平台,项目提供可视化拖拽编辑器,采用MIT开源协议,适用于app.小程序等项目 ...

  8. 基于BootStrap框架构建快速响应的GPS部标监控平台

    最近一个客户要求将gps部标平台移植到bootStrap框架作为前端框架,符合交通部796部标只是他们的一个基本要求,重点是要和他们的冷链云物流平台进行适配.我自己先浏览了客户的云物流平台的界面,采用 ...

  9. 转:Highcharts图表控件的使用

    摘要 Highcharts图表控件是目前使用最为广泛的图表控件.本文将从零开始逐步为你介绍Highcharts图表控件.通过本文,你将学会如何配置Highcharts以及动态生成Highchart图表 ...

随机推荐

  1. 中国电信中兴F460光猫破解及路由级联设置

    http://blog.csdn.net/pipisorry/article/details/50636541 中国电信中兴F460光猫破解,获取超级密码,修改配置. 之前家里的宽带升级了,换成了光纤 ...

  2. 分布式进阶(八)Linux提示Unable to locate package该如何处理?

    Linux提示Unable to locate package该如何处理? 当你在修改Linux软件源的时候,提示Unable to locate package错误,这是由什么原因导致的呢?又该如何 ...

  3. 分布式进阶(四)Ubuntu 14.04下安装Tomcat 6

    Ubuntu 10.04下安装Tomcat 6 1,下载apache-tomcat6, 地址链接:http://archive.apache.org/dist/tomcat/tomcat-6/v6.0 ...

  4. Swing中经常会遇到的若干问题——JTable(持续更新)

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/40955213 (1)让组件在屏幕中央显示 public s ...

  5. Android利用ViewPager仿微信主界面-android学习之旅(78)

    首先是介绍ViewPager这个控件 ,这个控件需要pagerAdapter作为容器来提供数据,同时pagerAdapter的数据源是View数组 效果图如下 部分代码如下,实现如下的方法 mPage ...

  6. mysql进阶(二十三)数据库事务四大特性

    数据库事务四大特性       原子性.一致性.分离性.持久性 原子性  事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行.这种特性称为 ...

  7. Android Widget 开发详解(二) +支持listView滑动的widget

    转载请标明出处:http://blog.csdn.net/sk719887916/article/details/47027263 不少开发项目中都会有widget功能,别小瞧了它,他也是androi ...

  8. 集群通信组件tribes之通道拦截器

    拦截器应该可以说是一个很经典的设计模式,它有点类似于过滤器,当某信息从一个地方流向目的地的过程中,可能需要统一对信息进行处理,如果考虑到系统的可扩展性和灵活性通常就会使用拦截器模式,它就像一个个关卡被 ...

  9. python-inotify 在linux上安装

    python-inotify 在linux上安装 0 下载 $ wget --no-check-certificate https://pypi.python.org/packages/source/ ...

  10. Android中代码运行指定的Apk

    有时候,当我们编写自己的应用的时候,需要通过代码实现指定的apk,安装指定的主题,或者安装新的apk.可以通过以下方法实现: private void installAPK(String apkUrl ...