当前位置: 首页 > 知识库问答 >
问题:

甜甜圈图ApachePOI

苏麒
2023-03-14

我正在尝试用ApachePOI创建甜甜圈图,但没有任何信息或示例。我尝试使用饼图的例子,但没有成功。你能帮我解决这个问题吗?

共有1个答案

平航
2023-03-14

首先请注意,对于以下每个解决方案,都需要所有模式的完整jarooxml-schemas-1.4.jar(较旧版本的较低版本),如常见问题N10025所述。

apache poi中还没有一个甜甜圈图表数据类型。所以最简单的方法和在大多数apache poi版本中可用的方法是使用org.openxmlformats.schemas.drawingml.x2006.chart.的低级类

例子:

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFDrawing;

import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDoughnutChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;

import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;

public class DoughnutChart {

    public static void main(String[] args) throws Exception {
        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("Sheet1");

        Row row;
        Cell cell;
        for (int r = 0; r < 3; r++) {
            row = sheet.createRow(r);
            cell = row.createCell(0);
            cell.setCellValue("S" + r);
            cell = row.createCell(1);
            cell.setCellValue(r+1);
        }

        XSSFDrawing drawing = (XSSFDrawing)sheet.createDrawingPatriarch();
        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 5, 20);

        XSSFChart chart = drawing.createChart(anchor);

        CTChart ctChart = ((XSSFChart)chart).getCTChart();
        CTPlotArea ctPlotArea = ctChart.getPlotArea();
        CTDoughnutChart ctDoughnutChart = ctPlotArea.addNewDoughnutChart();
        ctDoughnutChart.addNewVaryColors().setVal(true);
        ctDoughnutChart.addNewHoleSize().setVal((short)50);
        CTPieSer ctPieSer = ctDoughnutChart.addNewSer();

        ctPieSer.addNewIdx().setVal(0);     

        CTAxDataSource cttAxDataSource = ctPieSer.addNewCat();
        CTStrRef ctStrRef = cttAxDataSource.addNewStrRef();
        ctStrRef.setF("Sheet1!$A$1:$A$3"); 
        CTNumDataSource ctNumDataSource = ctPieSer.addNewVal();
        CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
        ctNumRef.setF("Sheet1!$B$1:$B$3"); 

        // Data point colors; is necessary for showing data points in Calc
        int pointCount = 3; 
        for (int p = 0; p < pointCount; p++) {
            ctChart.getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
            ctChart.getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDPtArray(p)
                .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(DefaultIndexedColorMap.getDefaultRGB(p+10));
        }

System.out.println(ctChart);

        FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
        wb.write(fileOut);
        fileOut.close();
        wb.close();
    }
}

使用当前的apache poi 4.1.1可以提供自己的XDDFDoughnutChartData,如下所示:

import org.apache.poi.xddf.usermodel.chart.*;

import org.apache.poi.util.Beta;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDoughnutChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx;

@Beta
public class XDDFDoughnutChartData extends XDDFChartData {
    private CTDoughnutChart chart;

    public XDDFDoughnutChartData(XDDFChart parent, CTDoughnutChart chart) {
        super(parent);
        this.chart = chart;
        for (CTPieSer series : chart.getSerList()) {
            this.series.add(new Series(series, series.getCat(), series.getVal()));
        }
    }

    @Override
    protected void removeCTSeries(int n) {
        chart.removeSer(n);
    }

    @Override
    public void setVaryColors(Boolean varyColors) {
        if (varyColors == null) {
            if (chart.isSetVaryColors()) {
                chart.unsetVaryColors();
            }
        } else {
            if (chart.isSetVaryColors()) {
                chart.getVaryColors().setVal(varyColors);
            } else {
                chart.addNewVaryColors().setVal(varyColors);
            }
        }
    }

    public Integer getFirstSliceAngle() {
        if (chart.isSetFirstSliceAng()) {
            return chart.getFirstSliceAng().getVal();
        } else {
            return null;
        }
    }

    public void setFirstSliceAngle(Integer angle) {
        if (angle == null) {
            if (chart.isSetFirstSliceAng()) {
                chart.unsetFirstSliceAng();
            }
        } else {
            if (angle < 0 || 360 < angle) {
                throw new IllegalArgumentException("angle must be between 0 and 360");
            }
            if (chart.isSetFirstSliceAng()) {
                chart.getFirstSliceAng().setVal(angle);
            } else {
                chart.addNewFirstSliceAng().setVal(angle);
            }
        }
    }

    public Short getHoleSize() {
        if (chart.isSetHoleSize()) {
            return chart.getHoleSize().getVal();
        } else {
            return null;
        }
    }

    public void setHoleSize(Short size) {
        if (size == null) {
            if (chart.isSetHoleSize()) {
                chart.unsetHoleSize();
            }
        } else {
            if (size < 0 || 100 < size) {
                throw new IllegalArgumentException("size must be between 0 and 100");
            }
            if (chart.isSetHoleSize()) {
                chart.getHoleSize().setVal(size);
            } else {
                chart.addNewHoleSize().setVal(size);
            }
        }
    }

    @Override
    public XDDFChartData.Series addSeries(XDDFDataSource<?> category,
            XDDFNumericalDataSource<? extends Number> values) {
        final long index = this.series.size();
        final CTPieSer ctSer = this.chart.addNewSer();
        ctSer.addNewCat();
        ctSer.addNewVal();
        ctSer.addNewIdx().setVal(index);
        ctSer.addNewOrder().setVal(index);
        final Series added = new Series(ctSer, category, values);
        this.series.add(added);
        return added;
    }

    public class Series extends XDDFChartData.Series {
        private CTPieSer series;

        protected Series(CTPieSer series, XDDFDataSource<?> category,
                XDDFNumericalDataSource<? extends Number> values) {
            super(category, values);
            this.series = series;
        }

        protected Series(CTPieSer series, CTAxDataSource category, CTNumDataSource values) {
            super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values));
            this.series = series;
        }

        @Override
        protected CTSerTx getSeriesText() {
            if (series.isSetTx()) {
                return series.getTx();
            } else {
                return series.addNewTx();
            }
        }

        @Override
        public void setShowLeaderLines(boolean showLeaderLines) {
            if (!series.isSetDLbls()) {
                series.addNewDLbls();
            }
            if (series.getDLbls().isSetShowLeaderLines()) {
                series.getDLbls().getShowLeaderLines().setVal(showLeaderLines);
            } else {
                series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines);
            }
        }

        @Override
        public XDDFShapeProperties getShapeProperties() {
            if (series.isSetSpPr()) {
                return new XDDFShapeProperties(series.getSpPr());
            } else {
                return null;
            }
        }

        @Override
        public void setShapeProperties(XDDFShapeProperties properties) {
            if (properties == null) {
                if (series.isSetSpPr()) {
                    series.unsetSpPr();
                }
            } else {
                if (series.isSetSpPr()) {
                    series.setSpPr(properties.getXmlObject());
                } else {
                    series.addNewSpPr().set(properties.getXmlObject());
                }
            }
        }

        public Long getExplosion() {
            if (series.isSetExplosion()) {
                return series.getExplosion().getVal();
            } else {
                return null;
            }
        }

        public void setExplosion(Long explosion) {
            if (explosion == null) {
                if (series.isSetExplosion()) {
                    series.unsetExplosion();
                }
            } else {
                if (series.isSetExplosion()) {
                    series.getExplosion().setVal(explosion);
                } else {
                    series.addNewExplosion().setVal(explosion);
                }
            }
        }

        @Override
        protected CTAxDataSource getAxDS() {
            return series.getCat();
        }

        @Override
        protected CTNumDataSource getNumDS() {
            return series.getVal();
        }

        @Override
        protected void setIndex(long val) {
            series.getIdx().setVal(val);
        }

        @Override
        protected void setOrder(long val) {
            series.getOrder().setVal(val);
        }
    }
}

使用它可以使用XDDF创建一个甜甜圈图表。

例子:

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;


public class DoughnutChartXDDF {

  public static void main(String[] args) throws IOException {
    try (XSSFWorkbook wb = new XSSFWorkbook()) {
      XSSFSheet sheet = wb.createSheet("doughnutChart");
      final int NUM_OF_ROWS = 2;
      final int NUM_OF_COLUMNS = 10;

      // Create a row and put some cells in it. Rows are 0 based.
      Row row;
      Cell cell;
      for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
        row = sheet.createRow((short) rowIndex);
        for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
          cell = row.createCell((short) colIndex);
          if (rowIndex == 0) cell.setCellValue("Cat " + (colIndex + 1));
          else cell.setCellValue((colIndex + 1) * (rowIndex + 1));
        }
      }

      XSSFDrawing drawing = sheet.createDrawingPatriarch();
      XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 4, 10, 25);

      XSSFChart chart = drawing.createChart(anchor);
      chart.setTitleText("Doughnut Chart");
      chart.setTitleOverlay(false);
      XDDFChartLegend legend = chart.getOrAddLegend();
      legend.setPosition(LegendPosition.TOP_RIGHT);

      XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,
          new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
      XDDFNumericalDataSource<Double> val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
          new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));

      XDDFDoughnutChartData data = new XDDFDoughnutChartData(chart, chart.getCTChart().getPlotArea().addNewDoughnutChart());
      data.setVaryColors(true);
      data.setHoleSize((short)50);
      XDDFChartData.Series series = data.addSeries(cat, val);
      chart.plot(data);

      // Do not auto delete the title; is necessary for showing title in Calc
      if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
      chart.getCTChart().getAutoTitleDeleted().setVal(false);

      // Data point colors; is necessary for showing data points in Calc
      int pointCount = series.getCategoryData().getPointCount(); 
      for (int p = 0; p < pointCount; p++) {
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDPtArray(p)
          .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(DefaultIndexedColorMap.getDefaultRGB(p+10));
      }
 
      // Write the output to a file
      try (FileOutputStream fileOut = new FileOutputStream("ooxml-doughnut-chart.xlsx")) {
        wb.write(fileOut);
      }
    }
  }
}
 类似资料:
  • 以下是基本饼图的示例。 我们已经在Highcharts Configuration Syntax一章中看到了用于绘制图表的配置 。 下面给出了基本饼图的示例。 配置 (Configurations) 现在让我们看一下所采取的其他配置/步骤。 系列 (series) 将系列类型配置为基于饼图。 series.type决定图表的系列类型。 这里,默认值是“line”。 使用innerSize将inne

  • 本文向大家介绍不带内部饼图的HTML Highcharts甜甜圈图示例,包括了不带内部饼图的HTML Highcharts甜甜圈图示例的使用技巧和注意事项,需要的朋友参考一下 将数据提供为包含两个元素的数组的数组。设置innerSize并获取甜甜圈样式。 参数将具有- 设置大小的代码片段-

  • 问题内容: 我正在使用ChartJs如何在甜甜圈图表中呈现文本。 问题答案: 您必须修改以下代码: 然后在功能上

  • 当使用图表时。js库,我可以添加多个甜甜圈在我的页面上没有问题。 http://www.chartjs.org/docs/#doughnut-饼图 但是我找不到一种方法总是显示工具提示——不仅仅是当鼠标悬停在甜甜圈上时。有人知道这是否可能吗?

  • 如何在甜甜圈图表中呈现文本,我正在使用ChartJs。

  • 有些地理区域是围绕一个主要大都市的区域,其中每个都是一个不同的行政区。瑞士(事实上)和巴西的首都就是这种情况。 这些区域的GeoJSON数据定义为几何类型多边形或多边形。但在这两种情况下,当命令 启动,以便几何形状可以作为文本返回并存储在postGIS中 将生成以下错误: 我把它解释为多边形没有闭合。是的,但有皱纹。 一个人怎么处理这个有环有环的环?