Struts2结合Jfreechart实现数据报表统计

时间:2022-12-21 21:58:31

   最近在公司做了一个数据的报表统计,主要实现了数据的饼状图、柱状图、折线图展示,写了这篇博客和大家分享一下:

里面有学习jfreechart相关的jar文件和学习文档,大家可以下载下来进行查看,我这里下载的jfreechart版本是1.0.17,对于现在来说,应该算是最新版本了吧!

一、环境配置:

1、导入struts相关jar包,我这里使用的是struts2

2、导入struts与jfreechart结合的jar包,struts2-jfreechart-plugin-2.3.1.jar,这个jar包在struts里面可能就已经存在了,这是struts2在这方面最好了处理,因为我们的jfreechart就是针对于java语言做报表工作的,很强大哦!

3、导入jfreechart核心包,解压我的文件,在jfreechart/lib/目录下,jcommon-1.0.21.jar、jfreechart-1.0.17.jar

4、关于struts2的部署和配置在这里就不像大家描述了,大家可以在网上找相关资料进行学习,我这个项目中运用到了struts2和spring框架,要用到jfreechart,我们在设置struts中的package配置时应该继承jfreechart-default,而不是像以前那样继承struts-default,理由应该是我们要在struts2中使用jfreechart就会用到struts2-jfreechart-pluginjar包,所以它里面除了封装自己的逻辑外,也继承了struts-default所以我们需要继承jfreechart-default:

<struts>
<package name="query" namespace="/" extends="jfreechart-default">
<action name="query" class="queryAction">
<result name="show" type="chart">
<param name="width">600</param>
<param name="height">400</param>
</result>
</action>
</package>
</struts>


 我给Action定义为QueryAction,因为我使用了spring,所以class="queryAction",如果大家只用到了struts2,那就得把action的全路径都写在里面了。这里type="chart",表示我们使用的是jfreechart输出,如果我们没有使用struts框架,只是使用基本的Servlet处理用户请求,那么我们需要在web.xml中进行相应的配置:

<servlet>    <servlet-name>DisplayChart</servlet-name>    <servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class></servlet><servlet-mapping>    <servlet-name>DisplayChart</servlet-name>    <url-pattern>/DisplayChart</url-pattern></servlet-mapping>


二、Action处理:

我们编写的Action中需定义一个JFreeChart对象,名称也必须为chart,可能是框架规定的,然后提供其相应的set和get方法:

public class QueryAction {                                                              private JFreeChart chart;                                                              public JFreeChart getChart() {        return chart;    }                                                          public void setChart(JFreeChart chart) {        this.chart = chart;    }}

我们在处理逻辑的时候只需要获得相应的JfreeChart对象即可:

public String show() throws Exception {    String type=request.getParameter("type");    Map<String,Double> map=null;    if(type!=null&&type.equals("area")){        map=queryService.findRepairRecByArea();        this.chart = JfreeChartUtil.createPieChart("各地区产品数量统计", map);//饼状图    }else if(type!=null&&type.equals("person")){        List<Map<String,Object>> list=queryService.findRepairRec(PERSON);        map=new HashMap<String,Double>();        for(Map<String,Object> repairRec:list){            String person=repairRec.get("repair_person")+"";            Double count=Double.parseDouble(repairRec.get("count")+"");            map.put(person, count);        }        this.chart = JfreeChartUtil.createBarChart("各人员维修产品数量统计", "维修人员", "产品数量", map);//柱状图    }    //this.chart = JfreeChartUtil.createLineChart("折线图", "X轴标签", "Y轴标签");    return "show";}



我在逻辑处理的时候,把相应的图的逻辑封装为JfreeChartUtil类,传入相应的参数过去,其中数据的显示则是从后台查询出来的,然后自己封装为一个Map<String,Double>:其中键值为描述标签信息,值为相应的数值,然后在设置的时候循环遍历Map取得其中的键和值。

三、jsp页面:

jsp页面中的代码就很简单了,直接一个img标签,然后src中写*问的action名称即可:

<body><br/><br/> <center>  <img alt="jfreechart" src="query!show.do?type=area"/> </center></body>

我们在访问的时候直接访问这个jsp页面即可:http://localhost:8080/xroa/index.jsp,它会自动请求Action显示相应的报表;

四、逻辑处理,下面,让我们来看看我们的逻辑处理这一大块,说白了就是掌握里面的API,然后灵活调用就可以了,因为代码里面有注解,所以我就不多说了,大家可以看看代码,如果弄不懂,可以看我那个资源文件里面的中文文档,或者自己从网上进行查找,因为里面的类比较多,所以我就不一一把那些类写出来了,大家灵活运用就可以了!

1)创建饼状图:

Struts2结合Jfreechart实现数据报表统计

实现代码:

/** * 创建饼状图 * @param title 标题 * @param map 键值对 * @return */public static JFreeChart createPieChart(String title,Map<String,Double> map){    DefaultPieDataset dpd=createPieDataset(map);    // 创建PieChart对象(标题,数据集,是否显示图例,是否生成工具提示,是否生成URL链接)    JFreeChart chart = ChartFactory.createPieChart3D(title, dpd,            true, true, false);    setPie3DStyle(chart);    return chart;}                                   /** * 创建饼状图数据 * @param map * @return */private static DefaultPieDataset createPieDataset(Map<String,Double> map){    DefaultPieDataset dpd = new DefaultPieDataset();    Set<String> set=map.keySet();    for(Iterator<String> itor=set.iterator();itor.hasNext();){        String key=itor.next();        dpd.setValue(key, map.get(key));    }    return dpd;}                                   /** * 设置饼状图样式 * @param chart */private static void setPieStyle(JFreeChart chart){    PiePlot plot = (PiePlot) chart.getPlot();    Font font = new Font("宋体", Font.ITALIC, 12);    chart.getTitle().setFont(new Font("宋体", Font.BOLD, 22));    //方块距离饼的距离 只要负值就能把数据放到饼里      plot.setLabelFont(font);    //去掉label    //plot.setLabelGenerator(null);    //在label上显示百分比    //plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{2}"));    //如果百分比要显示一位小数    //plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{2}",new DecimalFormat("0.0"),new DecimalFormat("0.0%")));    //在label上显示实际数值    //plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{1}"));     //是否显示线 fasle就不显示了     //plot.setLabelLinkMargin(-0.8);     //plot.setLabelLinksVisible(false);     //有时我们想突出某一个来显示,需要加入下面一句:第一个参数是key,第二个参数是突出显示的大小(可以自己调整一下看看效果就明白了)       //plot.setExplodePercent("城管强拆",0.23);    //设置相应的数据显示效果    //StandardPieSectionLabelGenerator standarPieIG = new StandardPieSectionLabelGenerator("{0}:({1},{2})", new DecimalFormat("0.0"), new DecimalFormat("0.0"));      StandardPieSectionLabelGenerator standarPieIG = new StandardPieSectionLabelGenerator("{0}:({1},{2})", new DecimalFormat("0.0"), new DecimalFormat("0.0%"));    plot.setLabelGenerator(standarPieIG);     //没有数据的时候所显示的内容    plot.setNoDataMessage("没有相应的数据显示");    chart.getLegend().setItemFont(font);}


如果我们需要创建3D样式的饼状图,只需要修改其样式即可:

Struts2结合Jfreechart实现数据报表统计


/** * 设置饼状图3D样式 * @param chart */private static void setPie3DStyle(JFreeChart chart){    //获得3D的水晶饼图对象     PiePlot3D pieplot3d = (PiePlot3D) chart.getPlot();     //设置开始角度     pieplot3d.setStartAngle(150D);     //设置方向为”顺时针方向“     pieplot3d.setDirection(Rotation.CLOCKWISE);     //设置透明度,0.5F为半透明,1为不透明,0为全透明     pieplot3d.setForegroundAlpha(0.5F);     pieplot3d.setNoDataMessage("没有相应的数据显示");     Font font = new Font("宋体", Font.ITALIC, 12);    chart.getTitle().setFont(new Font("宋体", Font.BOLD, 22));    pieplot3d.setLabelFont(font);    chart.getLegend().setItemFont(font);    StandardPieSectionLabelGenerator standarPieIG = new StandardPieSectionLabelGenerator("{0}:({1},{2})", new DecimalFormat("0.0"), new DecimalFormat("0.0%"));    pieplot3d.setLabelGenerator(standarPieIG); }


2)创建柱状图(显示内容为单个数据):

Struts2结合Jfreechart实现数据报表统计

/**    * 创建柱状图    * @param title 标题    * @param XLabel X轴标签    * @param YLabel Y轴标签    * @param map 键值对    * @return    */public static JFreeChart createBarChart(String title,String XLabel,String YLabel,Map<String,Double> map){    DefaultCategoryDataset dataset=createBarDataSet(map);    //创建一个柱状图(图表标题,X轴显示标签,Y轴显示标签,数据集,图表方向(水平or垂直),是否显示图例[对于简单图应为false],是否生成工具,是否生成url链接)    JFreeChart chart = ChartFactory.createBarChart3D(title,XLabel, YLabel, dataset, PlotOrientation.VERTICAL, false, false, false);    setBarStyle(chart);    return chart;}                       /** * 创建柱状图数据 * @param list * @return */private static DefaultCategoryDataset createBarDataSet(Map<String,Double> map){    DefaultCategoryDataset dataset = new DefaultCategoryDataset();    Set<String> set=map.keySet();    for(Iterator<String> itor=set.iterator();itor.hasNext();){        String key=itor.next();        dataset.addValue(map.get(key), "", key);    }    return dataset;}                       /** * 设置柱状图样式 * @param chart */private static void setBarStyle(JFreeChart chart){    CategoryPlot plot=chart.getCategoryPlot();    //设置标题字体样式    chart.getTitle().setFont(new Font("黑体", Font.ITALIC,22));    //取得横轴和设置横轴样式    CategoryAxis categoryAxis = plot.getDomainAxis();    categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));    //横轴分类标签    categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);    categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 22));    //取得纵轴和设置纵轴样式    NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();    numberAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));                               //显示每个柱的数值,并修改该数值的字体属性       BarRenderer3D renderer = new BarRenderer3D();           renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());         renderer.setBaseItemLabelsVisible(true);         //默认的数字显示在柱子中,通过如下两句可调整数字的显示          //注意:此句很关键,若无此句,那数字的显示会被覆盖,给人数字没有显示出来的问题 ,将数字显示在柱状图上面       renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(                 ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));         renderer.setItemLabelAnchorOffset(10D);          //设置每个地区所包含的平行柱的之间距离           //renderer.setItemMargin(0.3);          plot.setRenderer(renderer);  }

创建带有多个数据的柱状图:

Struts2结合Jfreechart实现数据报表统计

不同的地方主要是数据提供不一样:在dataset.addValue()中第二个参数部位""或null就行了,我们也可以使用数组的方式提供:

/** * 创建柱状图数据的第二种方式 * @return */private static CategoryDataset createBarDataSet2(){    double[][] data = new double[][] {{1310, 1220, 1110, 1000},{720, 700, 680, 640},{1130, 1020, 980, 800},{440, 400, 360, 300}};    String[] rowKeys = { "pig", "beef", "chicken", "fish" };    String[] columnKeys = { "Guangzhou", "Shenzhen", "Dongguan", "Foshan" };    CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);    return dataset;}

 3)创建折线图:

Struts2结合Jfreechart实现数据报表统计

/** * 创建折线图 * @param title * @param XLabel * @param YLabel * @return */public static JFreeChart createLineChart(String title,String XLabel,String YLabel) {    //该数据的Demo由系统提供,故不传入相应的Map或List数据了    DefaultCategoryDataset dataset=createLineDataset();    // 定义图表对象(折线图名称,横坐标名称,纵坐标名称,数据, 水平显示图像)    JFreeChart chart = ChartFactory.createLineChart(title,XLabel,YLabel,dataset,PlotOrientation.VERTICAL,true,true,false);    setLineStyle(chart);    return chart;}     /** * 生成折线图数据 * @return */private static DefaultCategoryDataset createLineDataset() {    DefaultCategoryDataset linedataset = new DefaultCategoryDataset();    // 各曲线名称    String series1 = "冰箱";    String series2 = "彩电";    String series3 = "洗衣机";    // 横轴名称(列名称)    String type1 = "1月";    String type2 = "2月";    String type3 = "3月";    linedataset.addValue(0.0, series1, type1);    linedataset.addValue(4.2, series1, type2);    linedataset.addValue(3.9, series1, type3);    linedataset.addValue(1.0, series2, type1);    linedataset.addValue(5.2, series2, type2);    linedataset.addValue(7.9, series2, type3);    linedataset.addValue(2.0, series3, type1);    linedataset.addValue(9.2, series3, type2);    linedataset.addValue(8.9, series3, type3);    return linedataset;}     /** * 设置折线图样式 * * @param chart */private static void setLineStyle(JFreeChart chart){    CategoryPlot plot = chart.getCategoryPlot();    //设置标题字体样式    chart.getTitle().setFont(new Font("黑体", Font.ITALIC,22));    //取得横轴和设置横轴样式    CategoryAxis categoryAxis = plot.getDomainAxis();    categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));    //横轴分类标签    categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);    categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 22));    plot.setRangeGridlinesVisible(true); //是否显示格子线    plot.setBackgroundAlpha(0.3f); //设置背景透明度    NumberAxis rangeAxis = (NumberAxis)plot.getRangeAxis();    rangeAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));    //设置工具工具提示字体样式    chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 22));    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());    rangeAxis.setAutoRangeIncludesZero(true);    rangeAxis.setUpperMargin(0.20);    rangeAxis.setLabelAngle(Math.PI / 2.0);}


好了,在这里基本上就完成了,不过需要注意以下几点:

1)有人说使用中文会出现乱码现象,我想主要是没有设置相应的字体样式,我这里面都对其进行了设置,所以就不会出现乱码现象了;

2)除了柱状图、折线图、饼状图,还有其他的图,例如分布图、区域图、混合图等等,都可以通过里面提供的API进行创建,大家可以再网上查找相关的资料进行学习即可,学会举一反三;

3)我们如果不输出到页面,也可以使用文件的方式保存,里面有一个util类可以帮我们进行处理,获得相应的FileOutStream,传入到参数中

* 调用下面方法可以输出到相应的FileOutputStream
  * ChartUtilities.writeChartAsJPEG(out, quality, chart, width, height, info);

其中out为输出流对象,quality为输出图片的质量,chart为相应的JFreechart对象,宽度、高度、信息

当我们使用Servlet进行处理的时候,out可以使用response.getOutputStream获得;

4)还有很多的API在这里没有用到,里面其实还有很强大的功能,大家自己根据自己的项目需求去学习吧,这里只是一个指引而已哦,欢迎一起交流分享!!

本文出自 “HarderXin” 博客,请务必保留此出处http://8786457.blog.51cto.com/8776457/1389849