在open xml sdk 2.0中更新Embedded excel部件后,图表没有刷新

时间:2013-03-01 14:17:03

标签: openxml-sdk

我试图通过其他一些excel文件在power point中更新图表的嵌入式excel部分, 它正在更新嵌入式excel文件但更新图表。

我注意到的一件事是,一旦我从“编辑数据”选项回来,我就能看到图表中的更新。请帮我看看如何在open xml中刷新图表

我使用以下代码,

 PresentationDocument myDestDeck = PresentationDocument.Open(@"Presentation1.pptx", true);

        PresentationPart PresPart = myDestDeck.PresentationPart;
        SlidePart slidePart = PresPart.SlideParts.FirstOrDefault();
        ChartPart chartPart1 = slidePart.ChartParts.FirstOrDefault();

        EmbeddedPackagePart embeddedPackagePart1 = chartPart1.EmbeddedPackagePart;
        embeddedPackagePart1.FeedData(new FileStream(@"Output12.xlsx", FileMode.Open, FileAccess.ReadWrite));

        PresPart.Presentation.Save();
        myDestDeck.Close();

请帮忙

提前致谢,

1 个答案:

答案 0 :(得分:1)

我只在.docx上下文中使用Open XML,但我怀疑你在我想更新文档中的某些嵌入式字符时遇到了同样的问题。

假设我采用的相同方法对Power Point有效,图表在zip-package中有两个包含所有文件的数据点。 首先,您在excel文件中有数据条目(在word文档中将位于/ word / embeddings中) 除此之外,您还有一个数据缓存,其中包含(由于某种原因)您的文件中以xml格式显示的数据缓存。 (位于/ word / charts) 为了使您的新数据在打开文件时立即生效,您还需要更新文件。

我首先抓住图表部分来解决这个问题

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(name, true))
            {
                var mainPart = wordDoc.MainDocumentPart; //indlæs hovedpart af dokumentet
                DocumentFormat.OpenXml.Packaging.ChartPart[] charts = mainPart.ChartParts.ToArray(); //hent grafer
            }

您需要深入了解要编辑的图表中的DocumentFormat.OpenXml.Drawing 然后隔离DocumentFormat.OpenXml.Drawing.Charts.ChartReference 从那里,您可以获得您可以在Rels文件中查找的图表ID,以获取您需要编辑的图表xml的路径。

我没有在项目中编写那部分代码,但我可以随意分享这些混乱,所以你走了。这是从BookmarkStart到ChartReference的一种丑陋的挖掘方式。

[注意:RelsRID是一个字典,其ID为密钥,文件名为值。]

private String grab(BookmarkStart bookmarkStart)
    {
        //isolate chart
        #region grab
        var rids = RelsRID;
        DocumentFormat.OpenXml.Wordprocessing.Drawing elem = null;
        DocumentFormat.OpenXml.Drawing.Charts.ChartReference gd = null;
        try
        {
            elem = bookmarkStart.NextSibling().Elements<Drawing>().ElementAt(0); //første forsøg på at finde vores graf
        }
        catch (Exception)
        { //forsøg nummer 2
            OpenXmlElement testE = bookmarkStart.NextSibling();
            while (testE.LocalName.ToLower() != "drawing")
            {
                testE = testE.NextSibling();
                for (int i = 0; i < testE.Elements().Count(); i++)
                    if (testE.ElementAt(i).LocalName.ToLower() == "drawing") testE = testE.ElementAt(i);
            }
            elem = (DocumentFormat.OpenXml.Wordprocessing.Drawing)testE;
        }
        try
        { //first try at grabbing graph data
            gd = (DocumentFormat.OpenXml.Drawing.Charts.ChartReference)elem.Inline.Graphic.GraphicData.ElementAt(0);
        }
        catch (Exception)
        { //second possible route
            gd = (DocumentFormat.OpenXml.Drawing.Charts.ChartReference)elem.Anchor.Elements<Graphic>().First().Elements<GraphicData>().First().ElementAt(0);
        }
        var id = gd.Id;
        String matchname = "/word/" + rids[id.ToString()]; //create filepath
        #endregion
        return matchname;
    }

如何处理获取图表xml的文件路径取决于您。我并不是真的赞同这种方式,但它应该让你知道如何处理它。

当您完成路径整理后,您可以执行以下操作(使用我们在第一个代码段中提取的图表

public void EditGraph(BookmarkStart bookmarkStart, DocumentFormat.OpenXml.Packaging.ChartPart[] charts)
    {
        String check = grab(bookmarkStart);
        ChartPart chart = null;

        for (int i = 0; i < charts.Count(); i++) //loop th
        {
            chart = charts[i];
            if (check.ToLower().Equals(chart.Uri.ToString().ToLower()))
                break;
        }
        //chart now contains the chart-cache you are looking to edit.
    }

您现在可以选择编辑其包含的数据的方式。 我选择从图表中取出图表xml,将其从图表中删除,编辑我拉出的xml并将其重新放入。 但我确信你也可以直接用open-xml来做。 你得到像这样的情节元素

var plots = chart.ChartSpace.Elements<DocumentFormat.OpenXml.Drawing.Charts.Chart>();

我希望我知道一种更简单的方法来解释它,但这可以说是我能做的最好的事情。

最后,我从未真正找到一种从文档中提取Rels的好方法,所以我最终只是跳进了zip文件并将其拉出来。

我构建了像以前一样使用的rels-dictionary

private Dictionary<String, String> RelsRIDToFile()
    {
    String rels;
            using (MemoryStream memory = new MemoryStream())
            {
                using (ZipFile zip = ZipFile.Read("wordfile.docx"))
                {
                    ZipEntry e = zip["word/_rels/document.xml.rels"];
                    e.Extract(memory);
                }
                using (StreamReader reader = new StreamReader(memory))
                {
                    memory.Seek(0, SeekOrigin.Begin);
                    rels = reader.ReadToEnd();
                }
            }
        XmlDataDocument xml = new XmlDataDocument();
        xml.LoadXml(rels);
        XmlNodeList xmlnode;
        xmlnode = xml.GetElementsByTagName("Relationship");
        Dictionary<String, String> result = new Dictionary<string, string>();
        for (int i = 0; i < xmlnode.Count; i++)
        {
            var node = xmlnode[i];
            var atts = node.Attributes;
            String id = "";
            String target = "";
            for (int ii = 0; ii < atts.Count; ii++)
            {
                var att = atts[ii];
                if (att.Name.ToLower() == "id") id = att.Value;
                if (att.Name.ToLower() == "target") target = att.Value;
            }
            result[id] = target;
        }
        return result;
    }
祝你好运,如果我能说清楚的话,请告诉我。