2019-01-21 POI+XChart图形报告

POI+XChart图形报告

一、基础示例,写入Excel

生成一个图形,并将其写入 Excel 中。

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.xlsx";
    double[] xData = new double[]{0.0, 1.0, 2.0};
    double[] yData = new double[]{2.0, 1.0, 0.0};

    // Create Chart
    XYChart chart = QuickChart.getChart("Sample Chart", "X", "Y", "y(x)", xData, yData);
    // 将图表转换为byte数组
    byte[] bytes = BitmapEncoder.getBitmapBytes(chart, BitmapEncoder.BitmapFormat.PNG);

    try (XSSFWorkbook workbook = new XSSFWorkbook();
         ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
         FileOutputStream outputStream = new FileOutputStream(filePath)) {
        // 创建Excel
        XSSFSheet sheet = workbook.createSheet("图表");

        // 写入Excel的指定位置
        XSSFDrawing shapes = sheet.createDrawingPatriarch();
        XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 0, 0, 6, 10);
        shapes.createPicture(anchor, sheet.getWorkbook().addPicture(inputStream, HSSFWorkbook.PICTURE_TYPE_PNG));

        // 将Excel写到文件中
        workbook.write(outputStream);
    }
}
生成的基础图片

上面我们演示了如何将 XChart生成的图片导入 Excel,下面的部分,都会将生成的图形导出为图片,如果需要导入Excel的话,只需要将chart套入第一章即可。

二、将生成的图形导出成为图片

获取随机数的方法也是通用的,这里先给出,具体的数据应该根据业务而定:

/**
     * 获取随机数
     * @param numPoints 随机的数量
     * @return 随机数组
     */
    private double[] getRandomWalk(int numPoints) {

        double[] y = new double[numPoints];
        y[0] = 0;
        for (int i = 1; i < y.length; i++) {
            y[i] = y[i - 1] + Math.random() - .5;
        }
        return y;
    }

折线图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    XYChart chart = new XYChartBuilder().xAxisTitle("X").yAxisTitle("Y").width(600).height(400).build();
    chart.getStyler().setYAxisMin(-10.0);
    chart.getStyler().setYAxisMax(10.0);
    XYSeries series = chart.addSeries("新绿", null, getRandomWalk(200));
    series.setMarker(SeriesMarkers.NONE);

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}

效果如下:

输入图片说明

面积图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    // Create Chart
    XYChart chart = new XYChartBuilder().width(800).height(600).title(getClass().getSimpleName()).xAxisTitle("X").yAxisTitle("Y").build();

    // Customize Chart
    chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNE);
    chart.getStyler().setAxisTitlesVisible(false);
    chart.getStyler().setDefaultSeriesRenderStyle(XYSeries.XYSeriesRenderStyle.Area);

    // Series
    chart.addSeries("a", new double[] { 0, 3, 5, 7, 9 }, new double[] { -3, 5, 9, 6, 5 });
    chart.addSeries("b", new double[] { 0, 2, 4, 6, 9 }, new double[] { -1, 6, 4, 0, 4 });
    chart.addSeries("c", new double[] { 0, 1, 3, 8, 9 }, new double[] { -2, -1, 1, 0, 1 });

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}
面积图

饼状图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    PieChart chart = new PieChartBuilder().width(800).height(600).title(getClass().getSimpleName()).build();

    // Customize Chart
    Color[] sliceColors = new Color[] { new Color(224, 68, 14), new Color(230, 105, 62), new Color(236, 143, 110), new Color(243, 180, 159), new Color(246, 199, 182) };
    chart.getStyler().setSeriesColors(sliceColors);

    // Series
    chart.addSeries("Gold", 24);
    chart.addSeries("Silver", 21);
    chart.addSeries("Platinum", 39);
    chart.addSeries("Copper", 17);
    chart.addSeries("Zinc", 40);

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}
饼状图

散点图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    // Create Chart
    XYChart chart = new XYChartBuilder().width(800).height(600).build();

    // Customize Chart
    chart.getStyler().setDefaultSeriesRenderStyle(XYSeries.XYSeriesRenderStyle.Scatter);
    chart.getStyler().setChartTitleVisible(false);
    chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideSW);
    chart.getStyler().setMarkerSize(16);

    // Series
    List<Double> xData = new LinkedList<Double>();
    List<Double> yData = new LinkedList<Double>();
    Random random = new Random();
    int size = 1000;
    for (int i = 0; i < size; i++) {
        xData.add(random.nextGaussian() / 1000);
        yData.add(-1000000 + random.nextGaussian());
    }
    chart.addSeries("Gaussian Blob", xData, yData);


    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}
散点图

柱状图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    // Create Chart
    CategoryChart chart = new CategoryChartBuilder().width(800).height(600).title("Score Histogram").xAxisTitle("Score").yAxisTitle("Number").build();

    // Customize Chart
    chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW);
    chart.getStyler().setHasAnnotations(true);

    // Series
    chart.addSeries("test 1", Arrays.asList(0, 1, 2, 3, 4), Arrays.asList(4, 5, 9, 6, 5));

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}
柱状图

堆叠图

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    // Create Chart
    CategoryChart chart = new CategoryChartBuilder().width(800).height(600).title("Score Histogram").xAxisTitle("Mean").yAxisTitle("Count").build();

    // Customize Chart
    chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW);
    chart.getStyler().setAvailableSpaceFill(.96);
    chart.getStyler().setOverlapped(true);

    // Series
    Histogram histogram1 = new Histogram(getGaussianData(10000), 20, -20, 20);
    Histogram histogram2 = new Histogram(getGaussianData(5000), 20, -20, 20);
    chart.addSeries("histogram 1", histogram1.getxAxisData(), histogram1.getyAxisData());
    chart.addSeries("histogram 2", histogram2.getxAxisData(), histogram2.getyAxisData());

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}

private List<Double> getGaussianData(int count) {
    List<Double> data = new ArrayList<Double>(count);
    Random r = new Random();
    for (int i = 0; i < count; i++) {
        data.add(r.nextGaussian() * 10);
    }
    return data;
}
堆叠图

百分比堆叠柱状图

这个其实是堆叠图的变种。

@Test
public void generate() throws IOException {
    String filePath = "C:\\Users\\user\\Desktop\\first.png";

    CategoryChart chart = new CategoryChartBuilder().width(800).height(600).build();
    chart.getStyler().setChartBackgroundColor(Color.WHITE);
    chart.getStyler().setLegendBorderColor(Color.WHITE);
    chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW);
    chart.getStyler().setAvailableSpaceFill(0.7);
    chart.getStyler().setStacked(true);

    List<String> xData = Arrays.asList("学院A", "学院B", "学院C","学院D","学院E");

    chart.addSeries("得分A", xData, getGaussianData(5));
    chart.addSeries("得分B", xData, getGaussianData(5));
    chart.addSeries("得分C", xData, getGaussianData(5));
    chart.addSeries("得分D", xData, getGaussianData(5));

    BitmapEncoder.saveBitmap(chart, filePath, BitmapEncoder.BitmapFormat.PNG);
}

private List<Double> getGaussianData(int count) {
    List<Double> data = new ArrayList<Double>(count);
    for (int i = 0; i < count; i++) {
        data.add(RandomUtils.nextDouble(0,1) * 10);
    }
    return data;
}
百分比堆叠柱状图

参考:

(1) XChart Demo

(2) 自己

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容