如何使用 VSTO 和 C# 更改 PowerPoint 图表中的值?

Use*_*313 5 c# powerpoint interop vsto powerpoint-interop

我需要使用 VSTO 更改 PowerPoint 图表中的源数据。第一个代码片段显示了我如何从形状对象中获取系列。

SeriesCollection seriesCollection = shape.Chart.SeriesCollection();
Series series = seriesCollection.Item(1);
Run Code Online (Sandbox Code Playgroud)

我已经通过调用测试它是否有效

series.Delete()
Run Code Online (Sandbox Code Playgroud)

这将从图表中删除系列。但是,如果可能,我只想更改系列的值。我尝试了以下方法:

series.Values = myArray1;
series.XValues = myArray2;
Run Code Online (Sandbox Code Playgroud)

这会导致一个空图。(系列名称和标题保留,但数据丢失)。

有谁知道如何做到这一点?我目前的解决方案是在 excel 中重新生成图表并替换 PowerPoint 中的图表,但我希望有一种更有效的方法。

Cod*_*ler 5

Powerpoint 图表基于基础 Excel 工作表,图表数据存储在单元格中。如果您调用图表的上下文菜单并单击“编辑数据...”,Excel 应用程序将启动,其中包含图表中的值的工作表。

因此,您应该修改 Powerpoint 图表,而不是直接设置系列值。您应该通过更新基础 Excel 工作表中的单元格值来完成此操作。这是一个工作示例:

static void Main(string[] args)
{
    var powerPointApp = new Microsoft.Office.Interop.PowerPoint.Application();
    var presentation = powerPointApp.Presentations.Open(@"Presentation1.pptx");
    var slide = presentation.Slides[1];
    var shape = slide.Shapes[1];

    var chartData = shape.Chart.ChartData;
    chartData.Activate();

    var workbook = chartData.Workbook;
    workbook.Application.Visible = false;
    var dataSheet = workbook.Worksheets[1];

    double[] newData = {1, 2, 3, 4, 5};

    var colNumber = 2;
    var firstRowNumber = 2;

    //  Clearing previous data
    dataSheet.UsedRange.Columns[colNumber, Type.Missing].Clear();

    for (var i = 0; i < newData.Length; ++i)
    {
        dataSheet.Cells[firstRowNumber + i, colNumber] = newData[i];
    }

    //  Saving and closing Excel workbook before presentation could be saved.
    workbook.Close(true);
    presentation.Save();
    presentation.Close();
    powerPointApp.Quit();
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中有两个硬编码值:

var colNumber = 2;
var firstRowNumber = 2;
Run Code Online (Sandbox Code Playgroud)

图表基础工作表具有预定义的结构。例如,对于默认图表,它构建以下工作簿:

在此输入图像描述

因此,在修改工作表中的数据时,您可以依赖以下假设:

  • 值系列的第一行等于 2。
  • 特定系列对应的列等于1 + series indexSeriesCollection.Item(object Index)这里的系列索引与您传递给调用以获取系列的索引相同(从 开始1)。因此,第二个工作表列对应于第一个图表系列,依此类推。

更新(对于瀑布图的问题)

瀑布图的问题也在我的环境中重现。我检查了所有其他 15 种图表类型,其中以下类型发生了相同的错误:

  • 树形图
  • 旭日
  • 直方图
  • 盒子和晶须
  • 瀑布

问题的根本原因是chartData.Activate()调用实际上并没有打开与图表关联的工作表。该问题特定于 Interop,因为如果您在 PowerPoint 应用程序中选择“编辑数据...”,工作表将成功打开。

所有这些图表都是在 Office 2016 中添加的。对于 Office 早期版本中提供的图表来说,一切正常。该问题似乎是由 Interop 程序集与 2016 Office 集成的问题引起的。Office 2016 仍然没有主互操作程序集,它仍然随 Office 2013 的 PIA 一起提供。不幸的是,我无法针对此特定问题提出修复或解决方法。我们必须等待微软团队的修复。