效果
实现
import com.gideon.entity.ChartPosition;
import com.gideon.entity.LineChart;
import com.gideon.entity.PieChart;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.PresetColor;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ChartUtils {
private static XSSFChart createDrawingPatriarch(XSSFSheet sheet, ChartPosition chartPosition, String chartTitle) {
//创建一个画布
XSSFDrawing drawing = sheet.createDrawingPatriarch();
//前偏移量四个默认0
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, chartPosition.getCol1(), chartPosition.getRow1(), chartPosition.getCol2(), chartPosition.getRow2());
//创建一个chart对象
XSSFChart chart = drawing.createChart(anchor);
//标题
chart.setTitleText(chartTitle);
//标题是否覆盖图表
chart.setTitleOverlay(false);
return chart;
}
/**
* 创建饼图
*
* @param sheet 图表
* @see com.gideon.entity.PieChart 饼图数据的封装
* @see com.gideon.entity.ChartPosition 饼图的坐标位置
*/
public static void createPie(XSSFSheet sheet, ChartPosition chartPosition, PieChart pieChart) {
String titleName = pieChart.getTitleName();
List<String> titleList = pieChart.getTitleList();
List<Integer> dataList = pieChart.getDataList();
XSSFChart chart = createDrawingPatriarch(sheet, chartPosition, titleName);
//图例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
//分类轴标数据
XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromArray(titleList.toArray(new String[]{}));
XDDFNumericalDataSource<Integer> values = XDDFDataSourcesFactory.fromArray(dataList.toArray(new Integer[]{}));
XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
//设置为可变颜色
data.setVaryColors(true);
//图表加载数据
data.addSeries(countries, values);
// 饼图设置颜色
CTPlotArea plotArea = chart.getCTChart().getPlotArea();
CTPieSer ser = plotArea.getPieChartArray(0).getSerArray(0);
CTDPt dpt = ser.addNewDPt();
List<byte[]> bytes = new ArrayList<>();
// 设置RGB颜色
bytes.add(new byte[]{(byte) 51, (byte) 208, (byte) 189});
bytes.add(new byte[]{(byte) 254, (byte) 190, (byte) 107});
bytes.add(new byte[]{(byte) 254, (byte) 112, (byte) 110});
bytes.add(new byte[]{(byte) 81, (byte) 146, (byte) 255});
for (int i = 0; i < 4; i++) {
dpt.addNewIdx().setVal(i);
dpt.addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(bytes.get(i));
dpt = ser.addNewDPt();
}
// 绘制
chart.plot(data);
CTDLbls ctdLbls = chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();
ctdLbls.addNewShowVal().setVal(false);
ctdLbls.addNewShowLegendKey().setVal(false);
// 百分比
ctdLbls.addNewShowSerName().setVal(false);
ctdLbls.addNewShowPercent().setVal(true);
// 类别名称
ctdLbls.addNewShowCatName().setVal(false);
// 引导线
ctdLbls.addNewShowLeaderLines().setVal(false);
// 数据标签内
ctdLbls.addNewDLblPos().setVal(STDLblPos.Enum.forString("inEnd"));
}
}