2017-04-25 119 views
1

我一直試圖讓這個工作好幾天,並且在這裏作爲最後的手段發佈。如何在使用OpenXML的Word文檔中設置複選框值

背景 -我正在創建一個Web應用程序,它允許用戶將數據輸入到網頁中,並使用佔位符將此數據轉換爲Microsoft Word文檔。這個Word文檔是一個填充數據並保存到用戶計算機的模板。

已解決的功能 -我已設法使用用戶數據填充所有必需的文本字段。這完全沒有問題。我已經創建了一個搜索和替換方法,爲我做了所有這些,所以我不需要有關這方面的幫助。

問題 -包含在用戶在網頁上輸入的數據是幾個布爾值。這些布爾值將用於檢查或取消選中Word文檔中的某些複選框。 Word文檔中的每個複選框都有一個需要用來查找它的書籤。我已經嘗試了幾種方法來搜索Word文檔的整個xml,並更改分配給該特定複選框元素的值。從Word模板中提取

示例XML

<w:document> 
<w:body>   
    <w:tbl>   
     <w:tr>   
      <w:tc>   
       <w:p w:rsidR="007D2E4C" w:rsidRPr="00233E81" w:rsidRDefault="007D2E4C" w:rsidP="007D2E4C"> 
        <w:r> 
         <w:fldChar w:fldCharType="begin"> 
          <w:ffData> 
           <w:name w:val="cbxmeal0"/> 
           <w:enabled/> 
           <w:calcOnExit w:val="0"/> 
           <w:checkBox> 
            <w:sizeAuto/> 
            <w:default w:val="0"/> 
           </w:checkBox> 
          </w:ffData> 
         </w:fldChar> 
        </w:r> 
        <w:bookmarkStart w:id="10" w:name="cbxmeal0"/> 
        <w:r> 
         <w:rPr> 
          <w:sz w:val="20"/> 
         </w:rPr> 
         <w:instrText xml:space="preserve"> FORMCHECKBOX </w:instrText> 
        </w:r> 
        <w:r w:rsidR="00B128CE"> 
         <w:rPr> 
          <w:sz w:val="20"/> 
         </w:rPr> 
        </w:r> 
        <w:r w:rsidR="00B128CE"> 
         <w:rPr> 
          <w:sz w:val="20"/> 
         </w:rPr> 
         <w:fldChar w:fldCharType="separate"/> 
        </w:r> 
        <w:r> 
         <w:rPr> 
          <w:sz w:val="20"/> 
         </w:rPr> 
         <w:fldChar w:fldCharType="end"/> 
        </w:r> 
        <w:bookmarkEnd w:id="10"/> 
       </w:p> 
      </w:tc> 
     </w:tr> 
    </w:tbl> 
</w:body> 

上面的XML文本是一個超級簡化版本,但是結構是完全一樣的。此結構的更簡單版本是Document > Body > Table > Table_Row > Table_Cell > Paragraph > Run > Field_Char > Form_Field_Data > Checkbox

下面是我通過XML文本迭代試圖定位書籤和複選框的非常醜陋的方式。注意:我只打算讓它工作,然後我會稍後優化。

  foreach (var table in document.MainDocumentPart.Document.Body.ChildElements.Where(t => t is DocumentFormat.OpenXml.Wordprocessing.Table)) 
     { 
      foreach (var row in table.ChildElements.Where(r => r is DocumentFormat.OpenXml.Wordprocessing.TableRow)) 
      { 
       foreach (var cell in row.ChildElements.Where(c => c is DocumentFormat.OpenXml.Wordprocessing.TableCell)) 
       { 
        foreach (var paragraph in cell.ChildElements.Where(p => p is DocumentFormat.OpenXml.Wordprocessing.Paragraph)) 
        { 
         foreach (var run in paragraph.ChildElements.Where(r => r is DocumentFormat.OpenXml.Wordprocessing.Run)) 
         { 
          foreach (var fieldChar in run.ChildElements.Where(fc => fc is DocumentFormat.OpenXml.Wordprocessing.FieldChar)) 
          { 
           foreach (var formFieldData in fieldChar.ChildElements) 
           { 
            foreach (var child in formFieldData.ChildElements) 
            { 
             //Check bookmark name 
             //If bookmark name matches, 
             //Set checkbox value to true 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 

如果任何人都可以提供任何幫助,不管它是一個網站地址,或者實際的代碼,這將是我在這一過程中失去信心是非常有幫助的!另外,原諒我的LINQ使用,因爲我使用它的經驗很少!

軟件 -我使用的是Visual Studio 2015,Microsoft Office 2016和OpenXML 2.6(我認爲)。

回答

1

這應該對你有幫助。

using (var wordDoc = WordprocessingDocument.Open(@"C:\test\cb\checkbox.docx", true)) 
{ 
    MainDocumentPart mainPart = wordDoc.MainDocumentPart; 
    var document = mainPart.Document; 
    var bookmarks = document.Body.Descendants<BookmarkStart>(); 

    var myBookmark = bookmarks.First(bms => bms.Name == "cbxmeal0"); 
    Paragraph paragraph = (Paragraph)myBookmark.Parent; 

    Run myCheckbox = (Run)paragraph.Descendants<FieldCode>().First().Parent; 
    Run newRun = new Run(@" 
<w:r xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main""> 
    <w:fldChar w:fldCharType=""begin""> 
     <w:ffData> 
      <w:name w:val=""cbxmeal0"" /> 
      <w:enabled /> 
      <w:calcOnExit w:val=""0"" /> 
      <w:checkBox> 
       <w:sizeAuto /> 
       <w:default w:val=""1"" /> 
      </w:checkBox> 
     </w:ffData> 
    </w:fldChar> 
</w:r> 
"); 
    paragraph.InsertBefore(newRun, myCheckbox); 
} 

我已經根據您提供的XML創建了一個Word文檔。前幾行只是放大包含您的複選框的Run。

有趣的部分是我創建的「newRun」。您可以使用XML代碼創建它,這是我所做的,但簡單地說,它會在您的複選框中添加一個「FieldChar」,並將其設置爲選中狀態。我不太確定是否重要,它是在包含複選框的Run之前插入的,但在我的測試中,它是Word自己做的,這就是爲什麼我以同樣的方式完成它。

我希望它有幫助!

+0

謝謝Kaspar!當我下班回家並讓你知道時,我會測試它。 – Savlon

+0

更新:剛剛測試過,一切正常。卡斯帕,你是個天才!非常感謝你! – Savlon

相關問題