Apache POI 饼图(Pie Chart)Java 实现
概述
本文介绍如何使用 Apache POI 在 word 文档中生成饼图,文档格式要求为 docx,对应于 Apache POI 中的 XWPFDocument。文中最后会附上完整的代码实现。
Word 饼图成品展示
在开始之前,放一张我们将要实现的饼图,这张饼图直观的展示了各个专业选修人数的占比。
POI 饼图实现
1、首先创建一个饼图,并设置一个标题
XWPFDocument document = new XWPFDocument();
XWPFChart chart = document.createChart(14 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
// 显示在饼图上面的标题
chart.setTitleText(chartData.getTitle());
// 设置标题是否覆盖图表
chart.setTitleOverlay(false);
2、设置饼图数据源
饼图的数据源有两个:一个是分类数据源;另一个值数据源,即各个分类对应的数值。对应到上图分类有四个:英语、数学、计算机和财经。值数据源则是由各个专业的选修人数构成。
// 分类数据源,即各个专业
XDDFCategoryDataSource categoryDS = XDDFDataSourcesFactory.fromArray(new String[]{"英语", "数学", "计算机", "财经"});
// 值数据源,即各个专业的选修人数
XDDFNumericalDataSource<Number> valueDS = XDDFDataSourcesFactory.fromArray(new Integer[]{10, 20, 30, 50});
// 将数据源绑定到饼图上
XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
XDDFChartData.Series series = data.addSeries(categoryDS, valueDS);
// 为了在饼图上显示百分比等信息,需要调用下面的方法
series.setShowLeaderLines(true);
上面的代码中用了两行代码将数据源绑定到饼图,是为了方便调用 series.setShowLeaderLines(true)
,其实绑定数据源也可以用一行代码搞定:
XDDFChartData data = chart.createData(ChartTypes.PIE, categoryDS, valueDS);
3、设置图例并完成绘制
// 图例
XDDFChartLegend legend = chart.getOrAddLegend();
// 图例的位置显示在图的正下方
legend.setPosition(LegendPosition.BOTTOM);
// 让每个分类的颜色区分开来
data.setVaryColors(true);
// 绘制饼图
chart.plot(data);
至此,使用 Apache POI API 在 word 中绘制饼图基本完成,此时运行程序可以得到下面这张图:
可以看出这张图和成品图略有不同,主要是每块饼上的除了显示百分比还额外显示了图例标识、系列名称、分类名称和数值。如果想隐藏这些信息仅显示一个百分比该如何实现呢?
为了能够灵活的控制分类、系列和数值等是否显示,我们先定义以下方法:
// 控制分类名称是否显示
public void showCateName(CTPieSer series, boolean val) {
if (series.getDLbls().isSetShowCatName()) {
series.getDLbls().getShowCatName().setVal(val);
} else {
series.getDLbls().addNewShowCatName().setVal(val);
}
}
// 控制值是否显示
public void showVal(CTPieSer series, boolean val) {
if (series.getDLbls().isSetShowVal()) {
series.getDLbls().getShowVal().setVal(val);
} else {
series.getDLbls().addNewShowVal().setVal(val);
}
}
// 控制值系列名称是否显示
public void showSerName(CTPieSer series, boolean val) {
if (series.getDLbls().isSetShowSerName()) {
series.getDLbls().getShowSerName().setVal(val);
} else {
series.getDLbls().addNewShowSerName().setVal(val);
}
}
// 控制图例标识是否显示
public void showLegendKey(CTPieSer series, boolean val) {
if (series.getDLbls().isSetShowLegendKey()) {
series.getDLbls().getShowLegendKey().setVal(val);
} else {
series.getDLbls().addNewShowLegendKey().setVal(val);
}
}
有了上面的方法之后,在绘制之前,调用上面的方法隐藏图例标识、系列名称、分类名称和数值,仅保留百分比即可:
// 隐藏图例标识、系列名称、分类名称和数值
XDDFPieChartData.Series s = (XDDFPieChartData.Series) series;
CTPieSer ctPieSer = s.getCTPieSer();
showCateName(ctPieSer, false);
showVal(ctPieSer, false);
showLegendKey(ctPieSer, false);
showSerName(ctPieSer, false);
// 绘制
chart.plot(data);
// 生成文档
try (FileOutputStream fo = new FileOutputStream("D:\\pie.docx")) {
document.write(fo);
}
POI Maven 依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-full</artifactId>
<version>5.2.3</version>
</dependency>
注:如果仅仅是绘制饼图可以不需要 poi-ooxml-full,但是在绘制折线图等图的时候则需要引入该依赖。最后有必要强调一下,不同版本的 poi 所需要引入依赖是不同的,需要看你的项目使用的 poi 版本决定,官方中对这一点也有说明。
ooxml-schema 不同版本 poi 要求不同,选错版本可能出现一些诡异的报错。
或许你还对 XWPF 中绘制折线图和柱状图感兴趣:
有问题吗?点此反馈!
温馨提示:反馈需要登录