Excel“全部刷新”使用 OpenXML

发布于 2024-09-27 01:40:11 字数 177 浏览 8 评论 0原文

我有一个 excel 2007 文件(OpenXML 格式),它连接到 xml 文件。此连接会生成 Excel 表格和数据透视图。

我正在尝试找到一种使用 OpenXML SDK v2 执行与 Excel 中的“全部刷新”按钮相同的操作的方法。这样我就可以在提供新的 xml 文件后自动更新我的文件。

谢谢。

I have an excel 2007 file (OpenXML format) with a connection to an xml file. This connection generates an excel table and pivot charts.

I am trying to find a way with OpenXML SDK v2 to do the same as the "Refresh All" button in Excel. So that I could automatically update my file as soon as a new xml file is provided.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

渡你暖光 2024-10-04 01:40:11

对此有一个很好的解决方法。
使用 OpenXML,您可以在数据透视表中打开“打开文件时刷新数据”选项(右键单击数据透视表 -> 数据透视表选项 -> 数据选项卡)。
当用户首次打开电子表格时,这会导致自动刷新数据透视表。
代码:

  using (var document = SpreadsheetDocument.Open(newFilePath, true))
        {
            var uriPartDictionary = BuildUriPartDictionary(document);

            PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart1 = (PivotTableCacheDefinitionPart)uriPartDictionary["/xl/pivotCache/pivotCacheDefinition1.xml"]; 
            PivotCacheDefinition pivotCacheDefinition1 = pivotTableCacheDefinitionPart1.PivotCacheDefinition;
            pivotCacheDefinition1.RefreshOnLoad = true;               
        }

您需要确定您的数据透视缓存定义的“路径” - 使用 OpenXML SDK 2.0 生产力工具来查找它。

BuildUriPartDictionary 是由 OpenXML SDK 2.0 生产力工具生成的标准方法。

protected Dictionary<String, OpenXmlPart> BuildUriPartDictionary(SpreadsheetDocument document)
    {
        var uriPartDictionary = new Dictionary<String, OpenXmlPart>();
        var queue = new Queue<OpenXmlPartContainer>();
        queue.Enqueue(document);
        while (queue.Count > 0)
        {
            foreach (var part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
            {
                uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
                queue.Enqueue(part.OpenXmlPart);
            }
        }
        return uriPartDictionary;
    }

另一个解决方案是将您的电子表格转换为启用宏,并在其中嵌入一个将刷新所有数据透视表的 VBA 脚本。
单击按钮时可能会发生这种情况,或者当用户打开电子表格时也会发生这种情况。
在这里您可以找到用于刷新数据透视表的 VBA 代码:
http://www.ozgrid.com/VBA/pivot-table-refresh.htm

Well there is quite good workaround for this.
Using OpenXML you can turn on "refresh data when opening the file" option in pivot table (right click on pivot table->PivotTable Options->Data tab).
This result in auto refresh pivot table when user first opens spreadsheet.
The code:

  using (var document = SpreadsheetDocument.Open(newFilePath, true))
        {
            var uriPartDictionary = BuildUriPartDictionary(document);

            PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart1 = (PivotTableCacheDefinitionPart)uriPartDictionary["/xl/pivotCache/pivotCacheDefinition1.xml"]; 
            PivotCacheDefinition pivotCacheDefinition1 = pivotTableCacheDefinitionPart1.PivotCacheDefinition;
            pivotCacheDefinition1.RefreshOnLoad = true;               
        }

you need to determine "path" to yours pivotCacheDefinition - use OpenXML SDK 2.0 Productivity Tool to look for it.

BuildUriPartDictionary is a standard method generated by OpenXML SDK 2.0 Productivity Tool

protected Dictionary<String, OpenXmlPart> BuildUriPartDictionary(SpreadsheetDocument document)
    {
        var uriPartDictionary = new Dictionary<String, OpenXmlPart>();
        var queue = new Queue<OpenXmlPartContainer>();
        queue.Enqueue(document);
        while (queue.Count > 0)
        {
            foreach (var part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
            {
                uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
                queue.Enqueue(part.OpenXmlPart);
            }
        }
        return uriPartDictionary;
    }

Another solution is to convert your spreadsheet to macroenabled, embed there a VBA script that will refresh all pivot tables.
This can happen on button click or again when user opens spreadsheet.
Here you can find VBA code to refresh pivot tables:
http://www.ozgrid.com/VBA/pivot-table-refresh.htm

无边思念无边月 2024-10-04 01:40:11

使用 Open XML 无法做到这一点。 Open XML 允许您处理文件中存储的数据并更改数据、公式和定义等。它实际上并不进行任何计算。

从技术上讲,Excel 自动化是可行的,但绝对不建议在服务器环境中使用它,并且如果可能的话最好避免在桌面上使用。

You can't do this with Open XML. Open XML allows you to work with the data stored in the file and change the data and formulas and definitions and such. It doesn't actually do any calculations.

Excel automation technically would work, but it's absolutely not recommended for a server environment and is best avoided on the desktop if at all possible.

拥醉 2024-10-04 01:40:11

我认为您可以执行此操作的唯一方法是遵循这种类型的方法。

  1. 将 Open XML 工作簿保存回 xlsx 文件。
  2. 使用 Excel 对象模型加载工作簿。
  3. 调用

ThisWorkbook.PivotCaches(yourIndex).Refresh();

ThisWorkbook.RefreshAll();

尽管我非常确定 RefreshAll 也可以工作。

  1. 使用对象模型保存工作簿并关闭它。
  2. 重新打开以与 xml 命名空间一起使用。

I think the only way you can do this is following this type of method..

  1. Save Open XML workbook back to a xlsx file.
  2. Load the workbook using the Excel object model.
  3. Call either

ThisWorkbook.PivotCaches(yourIndex).Refresh();

or

ThisWorkbook.RefreshAll();

although I was pretty sure RefreshAll would also work.

  1. Use the object model to Save the workbook and close it.
  2. Reopen for use with xml namespaces.
初心 2024-10-04 01:40:11

Bartosz Strutyński 提供的解决方案仅在工作簿包含数据透视表且共享相同的缓存。如果工作簿不包含数据透视表,代码将抛出 NullPointerException。如果工作簿包含使用不同缓存的数据透视表(这是数据源不同的情况),则只会刷新一组使用相同缓存的数据透视表。下面是基于 Bartosz Strutyński 的代码,没有上述限制,并且不依赖于了解 PivotCacheDefinition 对象的“路径”。该代码还内联了 BuildUriPartDictionary,它允许避免枚举 uriPartDictionary(以防在其他地方使用它),并使用显式类型来简化对所用类的文档搜索。

Dictionary<String, OpenXmlPart> uriPartDictionary = new Dictionary<String, OpenXmlPart>();
Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
    foreach (IdPartPair part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
    {
        uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
        queue.Enqueue(part.OpenXmlPart);
        PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart;
        if ((pivotTableCacheDefinitionPart = part.OpenXmlPart as PivotTableCacheDefinitionPart) != null)
        {
            pivotTableCacheDefinitionPart.PivotCacheDefinition.RefreshOnLoad = true;
        }
    }
}

The solution provided by Bartosz Strutyński will only work if the workbook does contain pivot tables and they share the same cache. If the workbook does not contain pivot tables, the code will throw a NullPointerException. If the workbook contains pivot tables that use different caches (which is the case when data sources are different), only one group of pivot tables that use the same cache will be refreshed. Below is the code based on Bartosz Strutyński's code, free of the aforementioned limitation, and not relying on knowing the "path" of PivotCacheDefinition object. The code also inlines BuildUriPartDictionary, which allows avoiding enumeration of uriPartDictionary in case it’s not used somewhere else, and uses explicit types, to ease searching documentation for the used classes.

Dictionary<String, OpenXmlPart> uriPartDictionary = new Dictionary<String, OpenXmlPart>();
Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
    foreach (IdPartPair part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
    {
        uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
        queue.Enqueue(part.OpenXmlPart);
        PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart;
        if ((pivotTableCacheDefinitionPart = part.OpenXmlPart as PivotTableCacheDefinitionPart) != null)
        {
            pivotTableCacheDefinitionPart.PivotCacheDefinition.RefreshOnLoad = true;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文