2010-09-28 45 views
2

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

我有兩個控件「名稱」和「年齡」的模板文檔。我可以很好地找到它們,但我不能在其中添加文本。我嘗試了很多東西,都無濟於事。

 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); 
      } 
     } 

所有幫助非常感謝。

乾杯,

Tim。

編輯 -

感謝您的答覆。接受你的建議,我已經嘗試使用生產力工具進行施工和鑽取,以找到要更新的子元素。你能告訴我,如果你能看到爲什麼這個代碼根本就不寫任何文件?

 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; 
         } 
        }  
       } 
+0

嗨,你有xRun聲明兩次,所以Visual Studio不編譯。這裏的變化: [code]運行xRun2 = xContentRun.Descendants ().FirstOrDefault(); [/ code] – 2015-03-28 23:34:02

回答

5

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

例如,如果一個SdtBlock:

((SdtBlock)sdt).SdtContentBlock 

然後你就可以添加內容(如添加的孩子)這一點。

From 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 
+0

謝謝,隊友。看到上面的編輯...乾杯。 – Hanshan 2010-09-29 04:36:10

1

幾個小時的痛苦之後,我解決了這個問題。

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

再次感謝我的解決方案!

+0

完整的代碼示例將不勝感激:-) – 2012-11-11 15:36:41

0

順便說一句,加入以下代碼行的foreach之前會自動清除所有現有的自定義XML:

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

任何想要的代碼在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的..!

相關問題