在C# .NetCore 2.0中用Open XML SDK 2.0创建Excel饼图与3D饼图
在.NET Core 2.0中用Open XML SDK创建饼图/3D饼图
我太懂这种找不到简洁示例的痛苦了——Open XML SDK生产力工具生成的代码全是冗余的默认配置,根本没法快速抓核心逻辑。下面给你两个极简的实现,核心步骤都拆出来了,你可以直接复用:
一、普通饼图示例
核心步骤:
- 创建基础Excel文档和工作表
- 填充图表所需的数据源(类别+数值)
- 定义图表的数据源范围
- 构建饼图的核心结构(ChartSpace -> Chart -> PlotArea -> PieChart -> PieSeries)
- 将图表嵌入工作表
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Drawing.Charts; public static void CreatePieChartExcel(string filePath) { // 创建Excel文档 using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook)) { // 添加工作簿和工作表 WorkbookPart workbookPart = document.AddWorkbookPart(); workbookPart.Workbook = new Workbook(); WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); worksheetPart.Worksheet = new Worksheet(new SheetData()); // 添加工作表到工作簿 Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets()); Sheet sheet = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "PieChartSheet" }; sheets.Append(sheet); // 填充数据源:A1=类别,B1=数值;A2-A4是类别,B2-B4是数值 SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>(); sheetData.Append( new Row(new Cell(new InlineText(new Text("类别"))) { CellReference = "A1" }, new Cell(new InlineText(new Text("数值"))) { CellReference = "B1" }), new Row(new Cell(new InlineText(new Text("产品A"))) { CellReference = "A2" }, new Cell(new CellValue("30")) { CellReference = "B2", DataType = CellValues.Number }), new Row(new Cell(new InlineText(new Text("产品B"))) { CellReference = "A3" }, new Cell(new CellValue("50")) { CellReference = "B3", DataType = CellValues.Number }), new Row(new Cell(new InlineText(new Text("产品C"))) { CellReference = "A4" }, new Cell(new CellValue("20")) { CellReference = "B4", DataType = CellValues.Number }) ); // 添加图表部件 DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>(); ChartPart chartPart = drawingsPart.AddNewPart<ChartPart>(); ChartSpace chartSpace = new ChartSpace(); Chart chart = chartSpace.AppendChild(new Chart()); // 定义图表标题和图例(可选,可移除) chart.AppendChild(new Title(new ChartText(new RichText(new Paragraph(new Run(new Text("产品销量占比"))))), new Legend()); // 构建绘图区域和饼图 PlotArea plotArea = chart.AppendChild(new PlotArea()); PieChart pieChart = plotArea.AppendChild(new PieChart()); // 定义饼图系列:绑定数据源 PieSeries pieSeries = pieChart.AppendChild(new PieSeries( new Index() { Val = 0 }, new Order() { Val = 0 }, new SeriesText(new RichText(new Paragraph(new Run(new Text("销量")))) )); // 绑定类别数据(A2:A4) pieSeries.AppendChild(new CategoryAxisData(new StringReference( new Formula("PieChartSheet!$A$2:$A$4"), new StringCache(new PointCount() { Val = 3 }, new NumericPoint(new Index() { Val = 0 }, new NumericValue("产品A")), new NumericPoint(new Index() { Val = 1 }, new NumericValue("产品B")), new NumericPoint(new Index() { Val = 2 }, new NumericValue("产品C")) ) ))); // 绑定数值数据(B2:B4) pieSeries.AppendChild(new Values(new NumberReference( new Formula("PieChartSheet!$B$2:$B$4"), new NumberingCache(new PointCount() { Val = 3 }, new NumericPoint(new Index() { Val = 0 }, new NumericValue("30")), new NumericPoint(new Index() { Val = 1 }, new NumericValue("50")), new NumericPoint(new Index() { Val = 2 }, new NumericValue("20")) ) ))); // 保存图表 chartPart.ChartSpace = chartSpace; // 将图表嵌入工作表的指定位置(比如D2单元格开始) worksheetPart.Worksheet.AppendChild(new Drawing() { Id = worksheetPart.GetIdOfPart(drawingsPart) }); TwoCellAnchor anchor = new TwoCellAnchor( new FromMarker(new ColumnId("3"), new ColumnOffset("0"), new RowId("1"), new RowOffset("0")), new ToMarker(new ColumnId("9"), new ColumnOffset("0"), new RowId("15"), new RowOffset("0")), new GraphicFrame(new Graphic(new GraphicData(new ChartReference() { Id = drawingsPart.GetIdOfPart(chartPart) }) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" })) ); drawingsPart.WorksheetDrawing = new WorksheetDrawing(new Anchor(anchor)); } }
二、3D饼图示例
3D饼图和普通饼图的核心逻辑几乎一致,只需要把PieChart替换成Pie3DChart,并可添加少量3D相关配置(比如深度百分比):
public static void Create3DPieChartExcel(string filePath) { using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook)) { // 前面的文档创建、数据源填充步骤和普通饼图完全一致,这里省略重复代码,直接看图表部分 WorkbookPart workbookPart = document.AddWorkbookPart(); workbookPart.Workbook = new Workbook(); WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); worksheetPart.Worksheet = new Worksheet(new SheetData()); Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets()); Sheet sheet = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "3DPieChartSheet" }; sheets.Append(sheet); SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>(); // 填充数据源,和普通饼图一样 sheetData.Append( new Row(new Cell(new InlineText(new Text("类别"))) { CellReference = "A1" }, new Cell(new InlineText(new Text("数值"))) { CellReference = "B1" }), new Row(new Cell(new InlineText(new Text("产品A"))) { CellReference = "A2" }, new Cell(new CellValue("30")) { CellReference = "B2", DataType = CellValues.Number }), new Row(new Cell(new InlineText(new Text("产品B"))) { CellReference = "A3" }, new Cell(new CellValue("50")) { CellReference = "B3", DataType = CellValues.Number }), new Row(new Cell(new InlineText(new Text("产品C"))) { CellReference = "A4" }, new Cell(new CellValue("20")) { CellReference = "B4", DataType = CellValues.Number }) ); // 添加图表部件 DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>(); ChartPart chartPart = drawingsPart.AddNewPart<ChartPart>(); ChartSpace chartSpace = new ChartSpace(); Chart chart = chartSpace.AppendChild(new Chart()); chart.AppendChild(new Title(new ChartText(new RichText(new Paragraph(new Run(new Text("产品销量占比(3D)"))))), new Legend()); PlotArea plotArea = chart.AppendChild(new PlotArea()); // 关键替换:用Pie3DChart代替PieChart Pie3DChart pie3DChart = plotArea.AppendChild(new Pie3DChart()); // 可选:设置3D饼图的深度百分比(默认是100,这里设为150) pie3DChart.AppendChild(new DepthPercent() { Val = 150 }); // 系列绑定和普通饼图完全一致 PieSeries pieSeries = pie3DChart.AppendChild(new PieSeries( new Index() { Val = 0 }, new Order() { Val = 0 }, new SeriesText(new RichText(new Paragraph(new Run(new Text("销量")))) )); pieSeries.AppendChild(new CategoryAxisData(new StringReference( new Formula("3DPieChartSheet!$A$2:$A$4"), new StringCache(new PointCount() { Val = 3 }, new NumericPoint(new Index() { Val = 0 }, new NumericValue("产品A")), new NumericPoint(new Index() { Val = 1 }, new NumericValue("产品B")), new NumericPoint(new Index() { Val = 2 }, new NumericValue("产品C")) ) ))); pieSeries.AppendChild(new Values(new NumberReference( new Formula("3DPieChartSheet!$B$2:$B$4"), new NumberingCache(new PointCount() { Val = 3 }, new NumericPoint(new Index() { Val = 0 }, new NumericValue("30")), new NumericPoint(new Index() { Val = 1 }, new NumericValue("50")), new NumericPoint(new Index() { Val = 2 }, new NumericValue("20")) ) ))); chartPart.ChartSpace = chartSpace; // 嵌入图表到工作表,和普通饼图一致 worksheetPart.Worksheet.AppendChild(new Drawing() { Id = worksheetPart.GetIdOfPart(drawingsPart) }); TwoCellAnchor anchor = new TwoCellAnchor( new FromMarker(new ColumnId("3"), new ColumnOffset("0"), new RowId("1"), new RowOffset("0")), new ToMarker(new ColumnId("9"), new ColumnOffset("0"), new RowId("15"), new RowOffset("0")), new GraphicFrame(new Graphic(new GraphicData(new ChartReference() { Id = drawingsPart.GetIdOfPart(chartPart) }) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" })) ); drawingsPart.WorksheetDrawing = new WorksheetDrawing(new Anchor(anchor)); } }
关键注意事项:
- 记得在.NET Core 2.0项目中安装NuGet包
DocumentFormat.OpenXml(版本选择兼容.NET Core 2.0的,比如2.8.1及以上) - 示例中的单元格范围、图表位置都可以根据需求调整,核心是数据源绑定和图表类型节点的选择
- 如果需要添加数据标签、调整饼图颜色,只需在
PieSeries或Pie3DChart节点下添加对应的子元素即可,比如DataLabels、Fill等
内容的提问来源于stack exchange,提问作者Faraaz
相关产品推荐
相关产品推荐

