我有一个连接到 xml 文件的 excel 2007 文件(OpenXML 格式)。此连接会生成一个 Excel 表和数据透视图。
我正在尝试使用 OpenXML SDK v2 找到一种与 Excel 中的“全部刷新”按钮相同的方法。这样我就可以在提供新的 xml 文件后立即自动更新我的文件。
谢谢你。
我有一个连接到 xml 文件的 excel 2007 文件(OpenXML 格式)。此连接会生成一个 Excel 表和数据透视图。
我正在尝试使用 OpenXML SDK v2 找到一种与 Excel 中的“全部刷新”按钮相同的方法。这样我就可以在提供新的 xml 文件后立即自动更新我的文件。
谢谢你。
那么有一个很好的解决方法。使用 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
我认为你能做到这一点的唯一方法是遵循这种方法..
ThisWorkbook.PivotCaches(yourIndex).Refresh();
或者
ThisWorkbook.RefreshAll();
虽然我很确定 RefreshAll 也会起作用。
使用 Open XML 无法做到这一点。Open XML 允许您使用存储在文件中的数据并更改数据、公式和定义等。它实际上不做任何计算。
Excel 自动化在技术上是可行的,但绝对不建议将其用于服务器环境,如果可能的话,最好避免在桌面上使用。
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;
}
}
}