Thứ Hai, 27 tháng 7, 2009

Convert an InfoPath 2007 form into a Word 2007 document using XSLT and C#

Tham khảo bài viết Convert an InfoPath 2007 form into a Word 2007 document using XSLT and C# để thực hiện việc Export InfoPath 2007 form data ra Word 2007. Chúng ta cần chú ý một số điểm sau:

- namespace của xsd phải có đủ trong xsl

- namespace trong w:document có đủ trong xsl:stylesheet của xsl

  • Open Microsoft Visual Studio 2005 and create a new InfoPath C# project.
  • Design an InfoPath form as shown in figure 1.

    Figure 1. InfoPath form in design mode.
  • The Main data source of the InfoPath form should resemble the following figure.

    Figure 2. Main data source of InfoPath form.
  • Create a docx file as shown in figure 3 and save it as template.docx. This Word 2007 document will be used as a template file to base your converted InfoPath forms on.

    Figure 3. The Word 2007 document to use as a template for converting InfoPath forms.
    The text ip_firstName, ip_lastName, ip_website, and table_cell_1 are used as placeholders just to make it easier later on to locate the positions in the XSLT stylesheet where to place references to the InfoPath form fields. Note that table_cell_1 is contained within a table. This table will be used to show the items from the Repeating Table on the InfoPath form.
  • Open Windows Explorer and browse to the template.docx file.
  • Copy template.docx, paste it, and rename it to template.zip.
  • Extract the files from the template.zip file.

    Figure 4. Contents of template.zip.
  • Double-click on the word folder to open it.

    Figure 5. Contents of the word folder in template.zip.
  • Open the document.xml file in Notepad and save it as transform.xsl in the same folder where template.docx is located.
  • Replace
       1: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 

    which is located at the beginning of the transform.xsl file with



       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
       2: <xsl:output method="xml" />
       3: <xsl:template match="/"> 

  • Append the following XSL tags to the end of the transform.xsl file:

       1: </xsl:template>
       2: </xsl:stylesheet> 

  • Switch to Microsoft Visual Studio 2005, go to the Solution Explorer, open the myschema.xsd file to view its code, copy all of the namespaces defined for the form (except for the default and xsd namespaces), and paste them as attributes of the xsl:stylesheet node in the transform.xsl file. The beginning xsl:stylesheet tag should now look something like:

       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
       2: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3: xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-12-31T07:11:15" 
       4: xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 

  • Copy all of the namespaces defined in the w:document node in the transform.xsl file, and paste them as attributes of the xsl:stylesheet node in the transform.xsl file. The beginning xsl:stylesheet tag should now look something like:

       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
       2: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3: xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-12-31T07:11:15" 
       4: xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
       5: xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
       6: xmlns:o="urn:schemas-microsoft-com:office:office" 
       7: xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
       8: xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
       9: xmlns:v="urn:schemas-microsoft-com:vml"
      10: xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
      11: xmlns:w10="urn:schemas-microsoft-com:office:word"
      12: xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      13: xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"

  • Search for ip_firstName in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:firstName" />


  • Search for ip_lastName in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:lastName" />


  • Search for ip_website in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:website" />


  • Search for table_cell_1 in the transform.xsl file and replace it with

    <xsl:value-of select="my:name" />


  • Search for the last </w:tblGrid> tag and append the following XSL code

    <xsl:for-each select="my:myFields/my:countries/my:country">


  • Search for the last </w:tr> tag and append the following XSL code

    </xsl:for-each>


  • The final transform.xsl file should now look something like this file.
  • Open the InfoPath form in design mode.
  • Select the Data > Data Connections... menu item.
  • Click on the Add... button on the Data Connections dialog box.
  • Select the Receive data option button and click on the Next > button.
  • Select the XML document option button and click on the Next > button.
  • Click on the Browse... button to navigate to and select the XSL file you created in step 20.
    Tip: Select All Files (*.*) in the Files of type drop-down list box to be able to see the XSLT file.
  • Click on the Next > button after you have selected the file and returned to the Data Connection Wizard dialog box.
  • Select Include the data as a resource file in the form template or template part and click on the Next > button.
  • Make sure that the Automatically retrieve data when form is opened checkbox is selected and then click on the Finish button.
  • Click on the Close button to close the Data Connections dialog box.
  • Go to the Solution Explorer window, click on the References node, and add a reference to the WindowsBase DLL that comes with the Microsoft .NET Framework 3.0.
  • Double-click on the button to open its Properties dialog box.
  • Click on the Edit Form Code... button and add the following code in the Clicked event handler that InfoPath created for you:

       1: // Define variables for the word template to use and file to create
       2: string wordTemplateFilePath = @"C:\InfoPath\ConvertToWord2007\template.docx";
       3: string wordPrintFilePath = @"C:\InfoPath\ConvertToWord2007\wordprint.docx";
       4: // Copy the template to create a new docx file
       5: File.Copy(wordTemplateFilePath, wordPrintFilePath, true);
       6: // Crack open the package
       7: Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite);
       8: // Retrieve the document.xml part of the new docx file
       9: PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));
      10: // Retrieve the xsl to use to transform the InfoPath form into document.xml
      11: DataSource ds = this.DataSources["transform"];
      12: XslCompiledTransform trans = new XslCompiledTransform();
      13: trans.Load(ds.CreateNavigator());
      14: // Create a StreamWriter to be able to write to the stream of the part
      15: using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
      16: {
      17: // Transform the InfoPath form and save the XML into the stream for the part
      18: trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);
      19: // Close the stream of the part
      20: partStream.Close();
      21: }
      22: // Write changes to the package 
      23: packWordPrint.Flush();
      24: // Close the package
      25: packWordPrint.Close();
      26: // Open the new docx file in Word 2007
      27: Process proc = new Process();
      28: proc.EnableRaisingEvents = false;
      29: proc.StartInfo.FileName = "winword";
      30: proc.StartInfo.Arguments = wordPrintFilePath;
      31: proc.Start();

    NOTE: Remember to change the path to the template.docx file as required by your own situation.


  • Add the following using statements to your form's code file:

    using System.IO;
    using System.IO.Packaging;
    using System.Diagnostics;
    using System.Xml.Xsl;


  • Give your InfoPath form Full Trust by going to Tools > Form Options and selecting the Security and Trust tab. And sign your InfoPath form with a digital certificate.
  • Build your InfoPath project.
  • Không có nhận xét nào:

    Đăng nhận xét