私は .docx コンテキストでのみ Open XML を使用しましたが、ドキュメントに埋め込まれた文字を更新したかったときと同じ問題が発生していると思われます。
私が取ったのと同じアプローチが Power Point にも有効であると仮定すると、チャートには、すべてのファイルを含む zip パッケージに 2 つのデータポイントがあります。最初に、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 ファイルで検索できる Charts ID を取得して、編集する必要があるチャート xml へのパスを取得します。
私はプロジェクトのコードのその部分を書きませんでしたが、私は混乱を共有する自由があるので、ここに行きます. これは、BookmarkStart から ChartReference を掘り下げる 1 つの醜い方法です。
[注: 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;
}
頑張ってください。何か明確にできるかどうか教えてください。