2017-04-25 122 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

相关问题