Java 實現報表功能 JFree

報表:將數據轉換爲可視化的圖表

maven:
<!--報表-->
<dependency>
  <groupId>jfree</groupId>
    <artifactId>jfreechart</artifactId>
  <version>1.0.13</version>
</dependency>

實現:

package com.kangshesi.utils;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.DateTickUnitType;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.labels.StandardPieToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.util.Rotation;

public class JFreeUtil {

    public static JFreeChart createPieChart( DefaultPieDataset dataset, String title, boolean is3D )
    {
        JFreeChart chart = null;
        if ( is3D )
        {
            chart = ChartFactory.createPieChart3D( title,   /* 圖表標題 */
                    dataset, /* 數據集 */
                    true,    /* 是否顯示圖例 */
                    true,    /* 是否顯示工具提示 */
                    true     /* 是否生成URL */
            );
        } else {
            chart = ChartFactory.createPieChart( title,     /* 圖表標題 */
                    dataset,   /* 數據集 */
                    true,      /* 是否顯示圖例 */
                    true,      /* 是否顯示工具提示 */
                    true       /* 是否生成URL */
            );
        }
        /* 設置標題字體==爲了防止中文亂碼:必須設置字體 */
        chart.setTitle( new TextTitle( title, new Font( "黑體", Font.ITALIC, 22 ) ) );
        /* 設置圖例的字體==爲了防止中文亂碼:必須設置字體 */
        chart.getLegend().setItemFont( new Font( "黑體", Font.BOLD, 12 ) );
        /* 獲取餅圖的Plot對象(實際圖表) */
        PiePlot plot = (PiePlot) chart.getPlot();
        /* 圖形邊框顏色 */
        plot.setBaseSectionOutlinePaint( Color.GRAY );
        /* 圖形邊框粗細 */
        plot.setBaseSectionOutlineStroke( new BasicStroke( 0.0f ) );
        /* 設置餅狀圖的繪製方向,可以按順時針方向繪製,也可以按逆時針方向繪製 */
        plot.setDirection( Rotation.ANTICLOCKWISE );
        /* 設置繪製角度(圖形旋轉角度) */
        plot.setStartAngle( 70 );
        /*
         * 設置突出顯示的數據塊
         * plot.setExplodePercent("One", 0.1D);
         * 設置背景色透明度
         */
        plot.setBackgroundAlpha( 0.7F );
        /* 設置前景色透明度 */
        plot.setForegroundAlpha( 0.65F );
        /* 設置區塊標籤的字體==爲了防止中文亂碼:必須設置字體 */
        plot.setLabelFont( new Font( "宋體", Font.PLAIN, 12 ) );
        /* 扇區分離顯示,對3D圖不起效 */
        if ( is3D )
            plot.setExplodePercent( dataset.getKey( 3 ), 0.1D );
        /* 圖例顯示百分比:自定義方式,{0} 表示選項, {1} 表示數值, {2} 表示所佔比例 ,小數點後兩位 */
        plot.setLabelGenerator( new StandardPieSectionLabelGenerator(
                "{0}:{1}\r\n({2})", NumberFormat.getNumberInstance(),
                new DecimalFormat( "0.00%" ) ) );
        /*
         * 圖例顯示百分比
         * plot.setLegendLabelGenerator(new
         * StandardPieSectionLabelGenerator("{0}={1}({2})"));
         * 指定顯示的餅圖爲:圓形(true) 還是橢圓形(false)
         */
        plot.setCircular( true );
        /* 沒有數據的時候顯示的內容 */
        plot.setNoDataMessage( "找不到可用數據..." );
        /* 設置鼠標懸停提示 */
        plot.setToolTipGenerator( new StandardPieToolTipGenerator() );
        /*
         * 設置熱點鏈接
         * plot.setURLGenerator(new StandardPieURLGenerator("detail.jsp"));
         */

        return(chart);
    }


    public static JFreeChart createBarChart( CategoryDataset dataset, String title, String x, String y, boolean is3D )
    {
        JFreeChart chart = null;
        if ( is3D )
        {
            chart = ChartFactory.createBarChart3D(                          /*
                     * 3D柱狀圖
                     * JFreeChart chart = ChartFactory.createLineChart3D( //3D折線圖
                     */
                    title,                                                  /* 圖表的標題 */
                    x,                                                      /* 目錄軸的顯示標籤 */
                    y,                                                      /* 數值軸的顯示標籤 */
                    dataset,                                                /* 數據集 */
                    PlotOrientation.VERTICAL,                               /* 圖表方式:V垂直;H水平 */
                    true,                                                   /* 是否顯示圖例 */
                    false,                                                  /* 是否顯示工具提示 */
                    false                                                   /* 是否生成URL */
            );
        } else {
            chart = ChartFactory.createBarChart(                            /*
                     * 柱狀圖
                     * JFreeChart chart = ChartFactory.createLineChart3D( //3D折線圖
                     */
                    title,                                                  /* 圖表的標題 */
                    x,                                                      /* 目錄軸的顯示標籤 */
                    y,                                                      /* 數值軸的顯示標籤 */
                    dataset,                                                /* 數據集 */
                    PlotOrientation.VERTICAL,                               /* 圖表方式:V垂直;H水平 */
                    true,                                                   /* 是否顯示圖例 */
                    false,                                                  /* 是否顯示工具提示 */
                    false                                                   /* 是否生成URL */
            );
        }

        /* ===============爲了防止中文亂碼:必須設置字體 */
        chart.setTitle( new TextTitle( title, new Font( "黑體", Font.ITALIC, 22 ) ) );

        LegendTitle legend = chart.getLegend();                                 /* 獲取圖例 */
        legend.setItemFont( new Font( "宋體", Font.BOLD, 12 ) );                  /* 設置圖例的字體,防止中文亂碼 */

        CategoryPlot plot = (CategoryPlot) chart.getPlot();                     /* 獲取柱圖的Plot對象(實際圖表) */
        /* 設置柱圖背景色(注意,系統取色的時候要使用16位的模式來查看顏色編碼,這樣比較準確) */
        plot.setBackgroundPaint( new Color( 255, 255, 204 ) );
        plot.setForegroundAlpha( 0.65F );                                       /* 設置前景色透明度 */

        /* 設置橫虛線可見 */
        plot.setRangeGridlinesVisible( true );
        /* 虛線色彩 */
        plot.setRangeGridlinePaint( Color.gray );

        CategoryAxis h = plot.getDomainAxis();                                  /* 獲取x軸 */
        h.setMaximumCategoryLabelWidthRatio( 1.0f );                            /* 橫軸上的 Lable 是否完整顯示 */
        h.setLabelFont( new Font( "宋體", Font.BOLD, 12 ) );                      /* 設置字體,防止中文亂碼 */
        h.setTickLabelFont( new Font( "宋體", Font.BOLD, 12 ) );                  /* 軸數值 */
        /* h.setCategoryLabelPositions(CategoryLabelPositions.UP_45);//45度傾斜 */

        plot.getRangeAxis().setLabelFont( new Font( "宋體", Font.BOLD, 12 ) );    /* Y軸設置字體,防止中文亂碼 */

        /* 柱圖的呈現器 */
        BarRenderer renderer = new BarRenderer();
        /*
         * 設置柱子寬度
         * renderer.setMaximumBarWidth(0.05);
         * 設置柱子高度
         * renderer.setMinimumBarLength(0.2);
         * 設置柱子邊框顏色
         */
        renderer.setBaseOutlinePaint( Color.BLACK );
        /* 設置柱子邊框可見 */
        renderer.setDrawBarOutline( true );
        /* 設置每個柱的顏色 */
        renderer.setSeriesPaint( 0, Color.BLUE );
        renderer.setSeriesPaint( 1, Color.GREEN );
        renderer.setSeriesPaint( 2, Color.RED );
        /* 設置每個地區所包含的平行柱的之間距離 */
        renderer.setItemMargin( 0.05 );
        /* 顯示每個柱的數值,並修改該數值的字體屬性 */
        renderer.setIncludeBaseInRange( true );
        renderer
                .setBaseItemLabelGenerator( new StandardCategoryItemLabelGenerator() );
        renderer.setBaseItemLabelsVisible( true );
        /* 設置柱的透明度 */
        plot.setForegroundAlpha( 1.0f );
        /* 給柱圖添加呈現器 */
        plot.setRenderer( renderer );

        /* 沒有數據的時候顯示的內容 */
        plot.setNoDataMessage( "找不到可用數據..." );

        return(chart);
    }


    public static JFreeChart createLineChart( String chartTitle, String chartXdesc, String chartYdesc, String periodType, int dateInterval, String timeFormat, XYDataset dataSet )
    {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
                chartTitle, chartXdesc, chartYdesc, dataSet, true, false, false
        );
        /* 設置標題 */
        chart.setTitle( new TextTitle( chartTitle, new Font( "黑體", Font.ITALIC, 22 ) ) );
        LegendTitle legend = chart.getLegend();
        legend.setItemFont( new Font( "宋體", Font.BOLD, 12 ) );                  /* 設置圖例的字體,防止中文亂碼 */
        XYPlot xyplot = (XYPlot) chart.getXYPlot();
        xyplot.setBackgroundPaint( new Color( 255, 255, 204 ) );
        xyplot.setForegroundAlpha( 0.65F );                                     /* 設置前景色透明度 */
        /* 設置橫虛線可見 */
        xyplot.setRangeGridlinesVisible( true );
        /* 虛線色彩 */
        xyplot.setRangeGridlinePaint( Color.gray );
        xyplot.getRangeAxis().setLabelFont( new Font( "宋體", Font.BOLD, 12 ) );  /* Y軸設置字體,防止中文亂碼 */
        xyplot.getDomainAxis().setLabelFont( new Font( "宋體", Font.BOLD, 12 ) ); /* X軸設置字體,防止中文亂碼 */

        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();

        if ( periodType.equalsIgnoreCase( "MONTH" ) )
        {
            dateaxis.setTickUnit( new DateTickUnit( DateTickUnit.MONTH, dateInterval ) );
        } else if ( periodType.equalsIgnoreCase( "DAY" ) )
        {
            dateaxis.setTickUnit( new DateTickUnit( DateTickUnit.DAY, dateInterval ) );
        } else if ( periodType.equalsIgnoreCase( "HOUR" ) )
        {
            dateaxis.setTickUnit( new DateTickUnit( DateTickUnit.HOUR, dateInterval ) );
        }
        dateaxis.setDateFormatOverride( new SimpleDateFormat( timeFormat ) );
        return(chart);
    }


    private static boolean drawToOutputStream( String destPath, JFreeChart chart, int width, int heigth ) {
        FileOutputStream fos = null;
        boolean returnValue = true;
        try {
            fos = new FileOutputStream(destPath);
            ChartUtilities.writeChartAsPNG(fos,    /* 指定目標輸出流 */
                    chart,  /* 圖表對象 */
                    width,  /* 寬 */
                    heigth, /* 高 */
                    null); /* ChartRenderingInfo信息 */
        } catch (IOException e) {
            e.printStackTrace();
            returnValue = false;
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return (returnValue);
        }
    }
        public static void 測試柱狀圖()
        {
            /* 初始化數據 */
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            dataset.setValue( 5000, "北京", "Corejava" );
            dataset.setValue( 3000, "上海", "Corejava" );
            dataset.setValue( 2000, "廣州", "Corejava" );

            dataset.setValue( 10000, "北京", "JavaWeb" );
            dataset.setValue( 6000, "上海", "JavaWeb" );
            dataset.setValue( 4000, "廣州", "JavaWeb" );

            dataset.setValue( 15000, "北京", "易用struts" );
            dataset.setValue( 5000, "上海", "易用struts" );
            dataset.setValue( 10000, "廣州", "易用struts" );

            dataset.setValue( 20000, "北京", "精通JSF" );
            dataset.setValue( 10000, "上海", "精通JSF" );
            dataset.setValue( 10000, "廣州", "精通JSF" );
            /* 生成圖表 */
            JFreeChart chart = createBarChart( dataset, "柱狀圖", "書名", "銷售數量", false );
            /* 生成圖片 */
            drawToOutputStream( "E:\\柱狀圖.JPG", chart, 640, 480 );
        }


        public static void 測試餅圖()
        {
            /* 初始化數據 */
            DefaultPieDataset dataset = new DefaultPieDataset();
            dataset.setValue( " 市場前期", new Double( 10 ) );
            dataset.setValue( " 立項", new Double( 15 ) );
            dataset.setValue( " 計劃", new Double( 10 ) );
            dataset.setValue( " 需求與設計", new Double( 10 ) );
            dataset.setValue( " 執行控制", new Double( 35 ) );
            dataset.setValue( " 收尾", new Double( 10 ) );
            dataset.setValue( " 運維", new Double( 10 ) );
            /* 生成圖表 */
            JFreeChart chart = createPieChart( dataset, "餅圖", true );
            /* 生成圖片 */
            drawToOutputStream( "E:\\餅圖.JPG", chart, 640, 480 );
        }
        public static void 測試曲線圖_MONTH()
        {
            /* 初始化數據 */
            String			chartTitle	= "訪問量統計圖形";
            String			chartSeriesDesc = "月訪問量曲線";
            String			chartXdesc	= "時間";
            String			chartYdesc	= "訪問量";
            String			timeFormat	= "MM"; /* yyyy-MM-dd */
            String			periodType	= "MONTH";
            int			dateInterval	= 1;
            TimeSeriesCollection	dataset		= new TimeSeriesCollection();
            TimeSeries		monthseries	= new TimeSeries( chartSeriesDesc, Month.class );
            monthseries.add( new Month( 1, 2001 ), 100 );
            monthseries.add( new Month( 2, 2001 ), 120 );
            monthseries.add( new Month( 3, 2001 ), 70 );
            monthseries.add( new Month( 4, 2001 ), 680 );
            monthseries.add( new Month( 5, 2001 ), 345 );
            monthseries.add( new Month( 6, 2001 ), 430 );
            monthseries.add( new Month( 7, 2001 ), 300 );
            monthseries.add( new Month( 8, 2001 ), 200 );
            monthseries.add( new Month( 9, 2001 ), 190 );
            monthseries.add( new Month( 10, 2001 ), 300 );
            monthseries.add( new Month( 11, 2001 ), 200 );
            monthseries.add( new Month( 12, 2001 ), 240 );
            /* 存儲至集合對象中 */
            dataset.addSeries( monthseries );
            /* 生成圖表 */
            JFreeChart chart = createLineChart( chartTitle, chartXdesc, chartYdesc,
                    periodType, dateInterval, timeFormat, dataset );
            /* 生成圖片 */
            drawToOutputStream( "E:\\曲線-月.JPG", chart, 640, 480 );
        }


        public static void 測試曲線圖_DAY()
        {
            /* 初始化數據 */
            String			chartTitle	= "訪問量統計圖形";
            String			chartSeriesDesc = "日訪問量曲線";
            String			chartXdesc	= "時間";
            String			chartYdesc	= "訪問量";
            String			timeFormat	= "dd"; /* yyyy-MM-dd */
            String			periodType	= "DAY";
            int			dateInterval	= 1;
            TimeSeriesCollection	dataset		= new TimeSeriesCollection();
            TimeSeries		dayseries	= new TimeSeries( chartSeriesDesc, Day.class );
            dayseries.add( new Day( 1, 1, 2010 ), 100 );
            dayseries.add( new Day( 2, 1, 2010 ), 200 );
            dayseries.add( new Day( 4, 1, 2010 ), 400 );
            dayseries.add( new Day( 5, 1, 2010 ), 600 );
            dayseries.add( new Day( 7, 1, 2010 ), 200 );
            dayseries.add( new Day( 8, 1, 2010 ), 400 );
            dayseries.add( new Day( 12, 1, 2010 ), 300 );
            dayseries.add( new Day( 23, 1, 2010 ), 500 );
            dayseries.add( new Day( 29, 1, 2010 ), 300 );
            /* 存儲至集合對象中 */
            dataset.addSeries( dayseries );
            /* 生成圖表 */
            JFreeChart chart = createLineChart( chartTitle, chartXdesc, chartYdesc,
                    periodType, dateInterval, timeFormat, dataset );
            /* 生成圖片 */
            drawToOutputStream( "E:\\曲線-天.JPG", chart, 640, 480 );
        }


        public static void 測試曲線圖_HOUR()
        {
            /* 初始化數據 */
            String			chartTitle	= "訪問量統計圖形";
            String			chartSeriesDesc = "小時訪問量曲線";
            String			chartXdesc	= "時間";
            String			chartYdesc	= "訪問量";
            String			timeFormat	= "hh"; /* yyyy-MM-dd */
            String			periodType	= "HOUR";
            int			dateInterval	= 1;
            TimeSeriesCollection	dataset		= new TimeSeriesCollection();
            TimeSeries		hourseries	= new TimeSeries( chartSeriesDesc, Hour.class );
            hourseries.add( new Hour( 1, 1, 1, 2010 ), 100 );
            hourseries.add( new Hour( 2, 1, 1, 2010 ), 200 );
            hourseries.add( new Hour( 3, 1, 1, 2010 ), 400 );
            hourseries.add( new Hour( 4, 1, 1, 2010 ), 600 );
            hourseries.add( new Hour( 5, 1, 1, 2010 ), 200 );
            hourseries.add( new Hour( 6, 1, 1, 2010 ), 400 );
            hourseries.add( new Hour( 7, 1, 1, 2010 ), 300 );
            hourseries.add( new Hour( 8, 1, 1, 2010 ), 500 );
            hourseries.add( new Hour( 9, 1, 1, 2010 ), 300 );
            /* 存儲至集合對象中 */
            dataset.addSeries( hourseries );
            /* 生成圖表 */
            JFreeChart chart = createLineChart( chartTitle, chartXdesc, chartYdesc,
                    periodType, dateInterval, timeFormat, dataset );
            /* 生成圖片 */
            drawToOutputStream( "E:\\曲線-小時.JPG", chart, 640, 480 );
        }


        public static void main( String[] args )
        {

            測試餅圖();
            測試柱狀圖();
            測試曲線圖_MONTH();
            測試曲線圖_DAY();
            測試曲線圖_HOUR();

        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章