1

CustomXMLPartのデータにバインドされたコンテンツコントロールを含むdocxWordドキュメントがあります。

このドキュメント(またはその中のブックマーク)は、INCLUDETEXTを使用して別のWordドキュメントに含まれます。

最初のドキュメントが2番目のドキュメントに含まれている場合、元のドキュメントからCustomXMLPartを取得する方法はありますか(Wordでドキュメントを参照しているVSTO Word Addinを既に実行しています)?

私がやりたいのは、コンテンツコントロールが引き続きXMLPartのデータにバインドされるように、2番目のドキュメントにすでに存在するCustomXMLPartsとマージすることです。

または、INCLUDETEXTフィールドを使用せずにこれを行う別の方法はありますか?

4

1 に答える 1

1

VSTOフィールドとIncludeTextフィールドを使用してこれを行うことはおそらく不可能であると判断し、代わりにaltChunksを使用して調査しました。

ファイルを開く前に、Open XML SDK 2を使用してファイルの処理をすでに行っていたので、そこでドキュメントをマージするために追加の作業が必要になりました。

altChunkメソッドを使用すると、独自のCustomXmlPartsを含む2番目のドキュメント全体が最初のドキュメントに埋め込まれますが、CustomXmlPartsは、ドキュメントが開かれ、2番目のドキュメントが最初のドキュメントとマージされるときにWordによって破棄されます。

私は次のようなコードになってしまいました。定義されたコンテンツコントロールをaltChunkデータに置き換え、特定のCustomXmlPartsをマージします。

    private static void CreateAltChunksInWordDocument(WordprocessingDocument doc, string externalDocumentPath)
    {
        foreach (var control in doc.ContentControls().ToList()) //Have to do .ToList() on this as when we update the Doc in the loop it stops enumerating otherwise
        {
            SdtProperties props = control.Elements<SdtProperties>().FirstOrDefault();
            if (props == null)
                continue;

            SdtAlias alias = props.Elements<SdtAlias>().FirstOrDefault();
            if (alias == null || !alias.Val.HasValue || alias.Val.Value != "External Template")
                continue;

            using (WordprocessingDocument externaldoc = WordprocessingDocument.Open(externalDocumentPath, false))
            {
                //Replace the Content Control with an AltChunk section, and stream in the external file
                string altChunkId = "AltChunkId" + Guid.NewGuid().ToString().Replace("{", "").Replace("}", "").Replace("-", "");

                AlternativeFormatImportPart chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                chunk.FeedData(File.OpenRead(externalDocumentPath));

                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;

                OpenXmlElement parent = control.Parent;
                parent.InsertAfter(altChunk, control);
                control.Remove();

                XDocument xDocMain;
                CustomXmlPart partMain = MyCommon.GetMyXmlPart(doc.MainDocumentPart, out xDocMain);

                XDocument xDocExternal;
                CustomXmlPart partExternal = MyCommon.GetMyXmlPart(externaldoc.MainDocumentPart, out xDocExternal);

                if (xDocMain != null && partMain != null && xDocExternal != null && partExternal != null)
                {
                    MyCommon.MergeXmlPartFields(xDocMain, xDocExternal);

                    //Save the updated part
                    using (Stream outputStream = partMain.GetStream())
                    {
                        using (StreamWriter ts = new StreamWriter(outputStream))
                        {
                            ts.Write(xDocMain.ToString());
                        }
                    }
                }
            }
        }
    }
于 2012-12-04T14:44:14.753 に答える