JFreeChart导出excel图表工具类

1.maven的pom.xml引入相关依赖

  <properties>
        <poi-version>3.17</poi-version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>${poi-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.1</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/jfree/jcommon -->
        <dependency>
            <groupId>jfree</groupId>
            <artifactId>jcommon</artifactId>
            <version>1.0.16</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/jfree/jfreechart -->
        <dependency>
            <groupId>jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.0.13</version>
        </dependency>
 
    </dependencies>

2.Demo


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.IntervalBarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.ui.TextAnchor;

import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.*;

public class JfreeChartUtils {

    public static void main(String[] args) throws Exception {
        // 画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)
        HSSFWorkbook wb = new HSSFWorkbook();
        //创建工作表
        HSSFSheet sheet = wb.createSheet("Sheet 1");
        //如果不使用Font,中文将显示不出来
        Font font = new Font("新宋体", Font.BOLD, 15);
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        //1.创建饼图数据
        List<NameValueVO> datas1 = new ArrayList<>();
        datas1.add(new NameValueVO("录播主机",(double) 1000));
        datas1.add(new NameValueVO("编码器",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器",(double) 1000));
        datas1.add(new NameValueVO("设备网络掉线4",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器1",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器2",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器3",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器4",(double) 1000));
        datas1.add(new NameValueVO("流转码服务器5",(double) 1000));

        //2.创建棒图数据
        List<NameValueVO> datas2 = new ArrayList<>();
        datas2.add(new NameValueVO("设备掉线1",(double) 1000));
        datas2.add(new NameValueVO("设备掉线2",(double) 1000));
        datas2.add(new NameValueVO("设备掉线3",(double) 1000));
        datas2.add(new NameValueVO("设备掉线4",(double) 1000));
        datas2.add(new NameValueVO("设备掉线5",(double) 1000));
        datas2.add(new NameValueVO("设备掉线6",(double) 1000));
        datas2.add(new NameValueVO("设备掉线7",(double) 1000));
        datas2.add(new NameValueVO("设备掉线8",(double) 1000));
        datas2.add(new NameValueVO("设备掉线9",(double) 1000));
        datas2.add(new NameValueVO("设备掉线10",(double) 1000));

        //3.画饼图
        testPieChart(wb,patriarch,font,datas1);
        //4.画棒图
        testBarChart(wb,patriarch,font,datas2);
        //5.折线图
        testLineChart(wb,patriarch,font);
        File file =new File("D://excel-demo/1.xlsx");
        if(file.exists()){
            file.delete();
        }
        FileOutputStream fileOut = new FileOutputStream(new File("D://excel-demo/1.xlsx"));
        wb.write(fileOut);
        fileOut.close();
    }

    /**
     * 创建饼图
     * @throws Exception
     */
    public static void testPieChart(HSSFWorkbook wb,HSSFPatriarch patriarch,Font font,List<NameValueVO> datas){
        try {
            //1.指定图片位置
            JFreeChart chart = createPieChart("故障设备类型比例", datas, font);
            //读取chart信息至字节输出流
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            ChartUtilities.writeChartAsPNG(byteArrayOut, chart, 1250, 680);
            //anchor主要用于设置图片的属性,指定图片位置
            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 2, (short) 1, (short) 19, (short) 40);
            anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
            //2.插入图片
            patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 创建棒图
     * @throws Exception
     */
    public static void testBarChart(HSSFWorkbook wb,HSSFPatriarch patriarch,Font font,List<NameValueVO> datas){
        try {
            //1.构建JFreeChart
            JFreeChart chart = createBarChart("故障类型比例",datas,"告警数量(个)",font);
            //读取chart信息至字节输出流
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            ChartUtilities.writeChartAsPNG(byteArrayOut, chart, 1250, 680);
            //anchor主要用于设置图片的属性,指定图片位置
            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 2, (short) 45, (short) 19, (short) 84);
            anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
            //2.插入图片
            patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 创建折线图
     * @param wb
     * @param patriarch
     * @param font
     */
    public static void testLineChart(HSSFWorkbook wb, HSSFPatriarch patriarch, Font font){
        try {
            String[] rowKeys = {"A平台","B平台"};
            String[] colKeys = {"0:00", "1:00", "2:00", "7:00", "8:00", "9:00","10:00", "11:00", "12:00", "13:00", "16:00", "20:00", "21:00","23:00"};
            double[][] data = {{4, 3, 1, 1, 1, 1, 2, 2, 2, 1, 8, 2, 1, 1},{6, 3, 8, 1, 1, 19, 2, 2, 5, 1, 8, 12, 1, 51}};
            String categoryAxisLabel = "时间";
            String valueAxisLabel = "告警数量(个)";

            CategoryDataset categoryDataset = DatasetUtilities.createCategoryDataset(rowKeys,colKeys, data);
            //1.指定图片位置
            JFreeChart chart = createLineChart("折线图",categoryAxisLabel,valueAxisLabel,font,categoryDataset);
            //读取chart信息至字节输出流
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            ChartUtilities.writeChartAsPNG(byteArrayOut, chart, 1250, 680);
            //anchor主要用于设置图片的属性,指定图片位置
            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 2, (short) 99, (short) 19, (short) 128);
            anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
            //插入图片
            patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * JFreeChart-棒图
     * @param title
     * @param datas
     * @param type
     * @param font
     * @return
     */
    public static JFreeChart createBarChart(String title, List<NameValueVO> datas, String type,Font font){
        try {
            Map<String, String> dataMap = tranBeanToMap(datas);
            DefaultCategoryDataset ds = new DefaultCategoryDataset();
            dataMap.forEach((key,value)->{
                ds.setValue(Double.parseDouble(value.toString()), "", key.toString());
            });
            //创建柱状图,柱状图分水平显示和垂直显示两种
            JFreeChart chart = ChartFactory.createBarChart(title, null, type, ds, PlotOrientation.VERTICAL, true, true, true);
            //设置整个图片的标题字体
            chart.getTitle().setFont(new Font("新宋体", Font.BOLD, 12));
            //设置提示条字体
            chart.getLegend().setItemFont(font);
            //得到绘图区
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
            // 自定义柱状图中柱子的样式
            CustomRender brender = new CustomRender();
            brender.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            brender.setBaseItemLabelsVisible(true);
            brender.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
            brender.setShadowVisible(false);
            brender.setIncludeBaseInRange(true);
            brender.setBarPainter(new StandardBarPainter());
            brender.setMaximumBarWidth(0.05);
            brender.setMinimumBarLength(0.05);

            plot.setRenderer(brender);
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);
            //设置范围轴(纵轴)字体
            plot.getRangeAxis().setLabelFont(font);
            plot.setForegroundAlpha(1.0f);
            //设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            return chart;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * JFreeChart-饼图
     * @param title
     * @param datas
     * @param font
     * @return
     */
    public static JFreeChart createPieChart(String title, List<NameValueVO> datas, Font font) {
        try {
            Map<String, String> dataMap = tranBeanToMap(datas);
            Set<Map.Entry<String, String>> set = dataMap.entrySet();
            DefaultPieDataset pds = new DefaultPieDataset();
            Iterator iterator = set.iterator();
            Map.Entry entry;
            while (iterator.hasNext()) {
                entry = (Map.Entry) iterator.next();
                pds.setValue(entry.getKey().toString(), Double.parseDouble(entry.getValue().toString()));
            }
            //生成一个饼图的图表:显示图表的标题、组装的数据、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createPieChart(title, pds, true, false, true);
            // 设置图片标题的字体
            chart.getTitle().setFont(font);
            // 得到图块,准备设置标签的字体
            PiePlot plot = (PiePlot) chart.getPlot();
            // 设置标签字体
            plot.setLabelFont(font);
            // 设置图例项目字体
            chart.getLegend().setItemFont(font);
            //设置plot的前景色透明度
            plot.setForegroundAlpha(0.7f);
            //设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            //设置标签生成器(默认{0})
            //{0}:key {1}:value {2}:百分比 {3}:sum
            plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}{1}({2})"));  // 一般在{1}后面加单位,如:{0}({1}次)/{2}
            return chart;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     *JFreeChart-折线图
     * @param categoryDataset 数据集
     * @param title 标题
     * @param categoryAxisLabel x轴名称
     * @param valueAxisLabel y轴名称
     * @param font
     *
     * @return
     */
    public static JFreeChart createLineChart(String title,String categoryAxisLabel, String valueAxisLabel,Font font,CategoryDataset categoryDataset) {
        try {
            JFreeChart chart = ChartFactory.createLineChart(title,categoryAxisLabel,valueAxisLabel,categoryDataset, PlotOrientation.VERTICAL, true, false, false);
            //设置整个图片的标题字体
            chart.getTitle().setFont(font);
            //设置提示条字体
            chart.getLegend().setItemFont(font);
            CategoryPlot plot = (CategoryPlot)chart.getPlot();
            LineAndShapeRenderer renderer = new LineAndShapeRenderer();
            renderer.setBaseShapesVisible(true); // series 点(即数据点)可见
            renderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见
            renderer.setUseSeriesOffset(true); // 设置偏移量
            renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            renderer.setBaseItemLabelsVisible(true);

            plot.setRenderer(renderer);
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);
            //设置范围轴(纵轴)字体
            plot.getRangeAxis().setLabelFont(font);
            plot.setForegroundAlpha(1.0f);
            //设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            return chart;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 构建折线图数据
     * @param rowKeys
     * @param colKeys
     * @param data
     * @return
     */
    public static CategoryDataset createCategoryDataset(String[] rowKeys,String[] colKeys, double[][] data){
        return DatasetUtilities.createCategoryDataset(rowKeys, colKeys, data);
    }


    /**
     * 数据机构转换,NameValueVO转map
     * @param data
     * @return
     */
    public static Map<String, String> tranBeanToMap(List<NameValueVO> data){
        if(CollectionUtils.isEmpty(data)){
            return null;
        }
        Map<String, String> map = new LinkedHashMap<>();
        for (NameValueVO nameValueVO : data){
            map.put(nameValueVO.getName().toString(), nameValueVO.getValue().toString());
        }
        return map;
    }

    static class CustomRender extends IntervalBarRenderer {
        private Paint[] colors;
        //初始化柱子颜色
        private String[] colorValues = {"#FF0000", "#0070C0", "#00AF4E", "#7030A0"};

        public CustomRender() {
            colors = new Paint[colorValues.length];
            for (int i = 0; i < colorValues.length; i++) {
                colors[i] = Color.decode(colorValues[i]);
            }
        }

        //每根柱子以初始化的颜色不断轮循
        public Paint getItemPaint(int i, int j) {
            return colors[j % colors.length];
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class NameValueVO<T> {
        private String name;
        private T value;
    }
}



 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值