簡體   English   中英

OpenXML將文本插入到內容控件Word 2007中

[英]OpenXML insert text into content control Word 2007

我正在學習OpenXML。 我一直在尋找幾個小時試圖找到如何做一個簡單的任務:在c#中的內容控件中插入文本。

我有一個模板文檔,其中包含兩個控件“Name”和“Age”。 我可以很好地找到它們,但我無法在其中添加文本。 我嘗試過很多東西,都無濟於事。

        byte[] templateBytes = System.IO.File.ReadAllBytes(fileName);
        using (MemoryStream templateStream = new MemoryStream())
        {
            templateStream.Write(templateBytes, 0, (int)templateBytes.Length);

            using (WordprocessingDocument outDoc = WordprocessingDocument.Open(templateStream, true))
            {
                MainDocumentPart mainPart = outDoc.MainDocumentPart;

                foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
                {
                    SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();

                    if (alias != null)
                    {
                        string sdtTitle = alias.Val.Value;

                        switch (sdtTitle)
                        {
                            case "Name":
                                // ¿Qué?
                                break;
                            case "Age":
                                // ¿Qué?
                                break;
                        }
                    }
                }

                outDoc.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
            }

            using (FileStream fileStream = new FileStream(savePath, System.IO.FileMode.CreateNew))
            {
                templateStream.WriteTo(fileStream);
            }
        }

所有幫助非常感謝。

干杯,

蒂姆。

編輯 -

謝謝你的回復。 根據您的建議,我嘗試使用生產力工具進行投射和挖掘,以找到要更新的子元素。 你能不能告訴我你是否可以看到為什么這段代碼根本沒有寫任何文件?

        foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
                {
                    SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();

                    if (alias != null)
                    {
                        SdtRun xRun = (SdtRun)sdt;
                        SdtContentRun xContentRun = xRun.Descendants<SdtContentRun>().FirstOrDefault();
                        Run xRun = xContentRun.Descendants<Run>().FirstOrDefault();
                        Text xText = xRun.Descendants<Text>().FirstOrDefault();

                        string sdtTitle = alias.Val.Value;

                        switch (sdtTitle)
                        {
                            case "Name":
                                xText.Text = "Whatever";                  
                                break;
                            case "Age":                    
                                xText.Text = "69";
                                break;
                        }
                    }     
                }

您需要將SdtElement轉換為它的任何內容,以便獲取其內容子項。

例如,如果它是一個SdtBlock:

    ((SdtBlock)sdt).SdtContentBlock

然后你可以添加東西(例如添加孩子)。

從MSDN ,繼承層次結構:

 DocumentFormat.OpenXml.Wordprocessing.SdtElement
     DocumentFormat.OpenXml.Wordprocessing.SdtBlock
     DocumentFormat.OpenXml.Wordprocessing.SdtCell
     DocumentFormat.OpenXml.Wordprocessing.SdtRow
     DocumentFormat.OpenXml.Wordprocessing.SdtRun
     DocumentFormat.OpenXml.Wordprocessing.SdtRunRuby

任何想要VB格式的代碼直接查找/替換鍵/值字典數組的人...

            Using document As WordprocessingDocument = WordprocessingDocument.Open(cls_sNewFilename, True)
                Dim mainPart As MainDocumentPart = document.MainDocumentPart
                Dim body As Body = mainPart.Document.Body

                'if custom xml content exists, delete it first
                mainPart.DeleteParts(Of CustomXmlPart)(mainPart.CustomXmlParts)

                For Each sdt As SdtElement In body.Descendants(Of SdtElement)().ToList()
                    Dim [alias] As SdtAlias = sdt.Descendants(Of SdtAlias)().FirstOrDefault()

                    If [alias] IsNot Nothing Then

                        If sdt.ToString() = "DocumentFormat.OpenXml.Wordprocessing.SdtRun" Then
                            Dim xStdRun As SdtRun = DirectCast(sdt, SdtRun)
                            Dim xStdContentRun As SdtContentRun = xStdRun.Descendants(Of SdtContentRun)().FirstOrDefault()
                            Dim xRun As Run = xStdContentRun.Descendants(Of Run)().FirstOrDefault()
                            Dim xText As Text = xRun.Descendants(Of Text)().FirstOrDefault()
                            Dim sdtTitle As String = [alias].Val.Value

                            xText.Text = dictReplacements.Item(sdtTitle)

                        ElseIf sdt.ToString() = "DocumentFormat.OpenXml.Wordprocessing.SdtBlock" Then
                            Dim xStdBlock As SdtBlock = DirectCast(sdt, SdtBlock)
                            Dim xStdContentBlock As SdtContentBlock = xStdBlock.Descendants(Of SdtContentBlock)().FirstOrDefault()
                            Dim xRun As Run = xStdContentBlock.Descendants(Of Run)().FirstOrDefault()
                            Dim xText As Text = xStdContentBlock.Descendants(Of Text)().FirstOrDefault()
                            Dim sdtTitle As String = [alias].Val.Value

                            xText.Text = dictReplacements.Item(sdtTitle)
                        End If
                    End If
                Next

                mainPart.Document.Save()
                document.Close()
            End Using

由於某種原因,最后一部分似乎是sdtBlock而不是sdtRun因此ElseIf ..!

經過幾個小時的痛苦,我解決了它。

問題有兩個:1)我需要一個mainPart.Document.Save(); 命令在那里。 2)我添加了一個帶有Content Control Toolkit的customXmlPart。 所以我假設這個customxml部分覆蓋了我在代碼中添加的文本,因為當我回到內容控制工具包並刪除xml部分時,它起作用了。

再次感謝plutext讓我加入解決方案!

順便說一句,在foreach之前添加以下代碼行將自動清除任何現有的自定義xml:

mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM