1

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

我注意到的一件事是,一旦我从“编辑数据”选项返回,我就可以在图表中看到更新。请帮助我如何在打开的 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();

请帮忙

提前致谢,

4

1 回答 1

1

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

假设我采用的相同方法对 Power Point 有效,则图表在包含所有文件的 zip 包中具有两个数据点。首先,您有 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 从那里您可以获得图表 ID,您可以在 Rels 文件中查找到获取您需要编辑的图表 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;
    }

祝你好运,如果我能澄清一些事情,请告诉我。

于 2013-03-27T12:55:28.173 回答