【问题标题】:Excel "Refresh All" with OpenXML使用 OpenXML 的 Excel“全部刷新”
【发布时间】:2011-04-23 15:41:03
【问题描述】:

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

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

谢谢。

【问题讨论】:

  • 关于数据透视表,我只是选中了每个数据透视表的“打开文件时刷新数据”选项。

标签: excel-2007 openxml office-2007 openxml-sdk


【解决方案1】:

我认为你能做到这一点的唯一方法就是遵循这种方法..

  1. 将 Open XML 工作簿保存回 xlsx 文件。
  2. 使用 Excel 对象模型加载工作簿。
  3. 拨打任一电话

ThisWorkbook.PivotCaches(yourIndex).Refresh();

ThisWorkbook.RefreshAll();

虽然我很确定 RefreshAll 也会起作用。

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

【讨论】:

  • 这是来自 COM excel 类的方法。它在 OpenXML 类中不可用,因为它用于操作 XML。最后,我认为这是不可能的。
  • Refresh All 应该刷新数据透视表。我将根据您上面的评论编辑我的答案。
  • 感谢您的宝贵时间,但我终于找到了解决问题的另一种方法:我为所有数据透视表设置了“打开文件时刷新”选项。然后我简单地将数据导出到一个主表中,以便excel文件自动更改。
  • 是的,您绝对可以将数据透视表设置为自动刷新,这只是 Excel 中的配置更改。由于性能问题,我假设您正在寻找一种手动刷新的方法,抱歉我的假设不好。您应该发布您的答案并接受它以供其他人参考。
【解决方案2】:

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

Excel 自动化在技术上是可行的,但绝对不建议将其用于服务器环境,并且尽可能避免在桌面上使用。

【讨论】:

    【解决方案3】:

    嗯,有一个很好的解决方法。 使用 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;               
            }
    

    您需要确定您的 pivotCacheDefinition 的“路径” - 使用 OpenXML SDK 2.0 Productivity Tool 来查找它。

    BuildUriPartDictionary 是 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;
        }
    

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2019-12-13
        • 2018-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多