【问题标题】:How can I change the values in a PowerPoint chart using VSTO and C#?如何使用 VSTO 和 C# 更改 PowerPoint 图表中的值?
【发布时间】:2017-04-04 08:50:54
【问题描述】:

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

SeriesCollection seriesCollection = shape.Chart.SeriesCollection();
Series series = seriesCollection.Item(1);

我已经通过调用测试了它的工作原理

series.Delete()

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

series.Values = myArray1;
series.XValues = myArray2;

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

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

【问题讨论】:

    标签: c# vsto interop powerpoint powerpoint-interop


    【解决方案1】:

    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();
    }
    

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

    var colNumber = 2;
    var firstRowNumber = 2;
    

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

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

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

    更新(瀑布图问题)

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

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

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

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

    【讨论】:

    • chartData.Activate() 是干什么用的?
    • 它打开与图表关联的工作表。如果不激活,下面对ChartData.Workbook 的调用将失败。
    • 所以最终用户可以看到它?我刚刚测试了它。它在折线图上没有Activate 的情况下工作。然而,它是当前选择的图表。也许这会有所作为?
    • 您可以通过将workbook.Application.Visible 设置为false 来隐藏Excel 应用程序。我刚刚将它添加到我的答案中。然而,Excel 窗口无论如何都会在它被隐藏之前出现片刻。 This question 解决了这个问题,但不幸的是它没有答案。我不确定代码在没有激活的情况下如何工作。即使我选择图表,它对我来说也失败了。如果图表在没有Activate() 的情况下成功更新,我相信你可以在没有这个调用的情况下进行更新。
    • 奇怪。那么瀑布图(图表类型 119)呢?此代码不起作用,因为 Workbook 即使在调用 Activate() 时也会抛出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多