首页 > 解决方案 > 使用 Open XML SDK 读取 Excel 图表模板 (*.crtx)

问题描述

我正在尝试阅读 Excel 图表模板 (mychart.crtx) 中使用的颜色。但我不知道如何使用 Open XML 工具包打开文件。使用 SDK 工具似乎不可能。

可以做到吗?

标签: openxmlopenxml-sdk

解决方案


这对于 Open XML SDK 确实是不可能的,因为它只提供WordprocessingDocument(for .docxetc.)、SpreadsheetDocument(for .xlsxetc.) 和PresentationDocument(for .pptxetc.) 类来打开 Word、Excel 和 PowerPoint 文档和模板。

但是,Office 文档和您的 Excel 图表模板 ( .crtx) 都基于开放打包约定 (OPC)。您可以使用System.IO.Packaging命名空间中提供的类来处理任何基于 OPC 的文档,包括那些 Excel 图表模板。

ChartTemplate.crtx下图显示了我为测试目的创建的示例的结构。我使用Open XML Package Editor for Modern Visual Studios来检查那个包。

Excel图表模板的封装结构

使用System.IO.Packaging类,Package类代表整个包(例如,ChartTemplate.crtx)。该类PackagePart表示包中包含的 XML 和其他文件。每个PackagePart都有一个URI(例如,,/chart/chart.xml/chart/charts/colors1.xml,一个内容类型,以及零个或多个与其他部分的关系。

以下代码片段打开示例Package,获取PackagePart,从部件加载根 XML 元素并做出某些断言来演示它得到了什么。

[Fact]
public void LoadRootElement_Chart_SuccessfullyLoaded()
{
    using Package package = Package.Open("Resources\\ChartTemplate.crtx", FileMode.Open, FileAccess.Read);
    PackagePart packagePart = package.GetPart(new Uri("/chart/chart.xml", UriKind.Relative));

    XElement rootElement = LoadRootElement(packagePart);

    Assert.Equal(C.chartSpace, rootElement.Name);
    Assert.NotEmpty(rootElement.Elements(C.chart).Elements(C.title));
    Assert.NotEmpty(rootElement.Elements(C.chart).Elements(C.plotArea));
    Assert.NotEmpty(rootElement.Elements(C.chart).Elements(C.legend));
}

LoadRootElement()方法很简单:

private static XElement LoadRootElement(PackagePart packagePart)
{
    using Stream stream = packagePart.GetStream(FileMode.Open, FileAccess.Read);
    return XElement.Load(stream);
}

我创建了一个辅助类C来提供所需的 XML 命名空间和名称以供XElement该类使用,这些名称与 和 一样XNamespaceXName是在命名空间中定义的System.Xml.Linq

private static class C
{
    public static readonly XNamespace c = "http://schemas.openxmlformats.org/drawingml/2006/chart";

    public static readonly XName chart = c + "chart";
    public static readonly XName chartSpace = c + "chartSpace";
    public static readonly XName lang = c + "lang";
    public static readonly XName legend = c + "legend";
    public static readonly XName plotArea = c + "plotArea";
    public static readonly XName title = c + "title";

    public static readonly XName val = "val";
}

与往常一样,可以在我的CodeSnippets GitHub 存储库中找到完整的源代码。查找ChartTemplateTests类。


推荐阅读