You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C# .NetCore 2.0中用Open XML SDK 2.0创建Excel饼图与3D饼图

在.NET Core 2.0中用Open XML SDK创建饼图/3D饼图

我太懂这种找不到简洁示例的痛苦了——Open XML SDK生产力工具生成的代码全是冗余的默认配置,根本没法快速抓核心逻辑。下面给你两个极简的实现,核心步骤都拆出来了,你可以直接复用:

一、普通饼图示例

核心步骤:

  1. 创建基础Excel文档和工作表
  2. 填充图表所需的数据源(类别+数值)
  3. 定义图表的数据源范围
  4. 构建饼图的核心结构(ChartSpace -> Chart -> PlotArea -> PieChart -> PieSeries)
  5. 将图表嵌入工作表
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:24:02