Click here to Skip to main content
15,884,425 members
Articles / Web Development / HTML

Generating Word Reports / Documents

Rate me:
Please Sign up or sign in to vote.
4.94/5 (122 votes)
4 Oct 2009CPOL22 min read 702.9K   8K   544  
Generate Word documents by appling XSLT on XML data.
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Xsl;
using System.IO;

namespace GeneratingMicrosoftWordReports.Engine
{
    public class Generation
    {
        /// <summary>
        /// Creates Word document from XML using XSLT
        /// </summary>
        /// <param name="xmlData">Report data as XML</param>
        /// <param name="nameOfXslt">XSLT transformation as Stream, used for document creation</param>
        /// <returns>Resulting Word document as byte[]</returns>
        public static byte[] GetWord(XmlReader xmlData, XmlReader xsltReader)
        {
            // Initialize needed variables
            XslCompiledTransform xslt = new XslCompiledTransform();
            XsltArgumentList args = new XsltArgumentList();

            using (MemoryStream swResult = new MemoryStream())
            {
                // Load XSLT to reader and perform transformation
                xslt.Load(xsltReader);
                xslt.Transform(xmlData, args, swResult);

                return swResult.ToArray();
            }
        }
        
        /// <summary>
        /// Generates List type Word report from DataTable
        /// </summary>
        /// <param name="reportHeader">Text to display in report header</param>
        /// <param name="dtData">DataTable containing data for word</param>
        /// <returns>Resulting Word document as Byte array</returns>
        public static byte[] GenericListReport(string reportHeader, DataTable dtData)
        {
            // default xslt
            string template = @"<?xml version='1.0' encoding='UTF-8' ?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fn='http://www.w3.org/2003/11/xpath-functions' xmlns:xf='http://www.w3.org/2002/08/xquery-functions'>
	<xsl:template match='/'>
		<html>
			<body>
				<h2>{0}</h2>
				<table border='0' width='100%'>
					<tr bgcolor='Gray'>
						{1}
					</tr>
					<xsl:for-each select='{2}'>
						<tr>
							{3}
						</tr>
					</xsl:for-each>
				</table>
			</body>
		</html>
	</xsl:template>
</xsl:stylesheet>";

            return GenericListReport(template, reportHeader, dtData);
        }

        /// <summary>
        /// Generates List type Word report from DataTable
        /// </summary>
        /// <param name="template">Xslt template to use in creation process</param>
        /// <param name="reportHeader">Text to display in report header</param>
        /// <param name="dtData">DataTable containing data for word</param>
        /// <returns>Resulting Word document as Byte array</returns>
        public static byte[] GenericListReport(string template, string reportHeader, DataTable dtData)
        {            
            // Generate Xslt

            /* {1}
             *  <th align='left'>Title</th>
                <th align='left'>Artist</th>
             */

            /* {3}
             *  <td><xsl:value-of select='title'/></td>
                <td><xsl:value-of select='artist'/></td>
             */

            StringBuilder cols = new StringBuilder();
            StringBuilder valueOfSelect = new StringBuilder();
            foreach (DataColumn dc in dtData.Columns)
            {
                cols.AppendFormat("<th align='left'>{0}</th>", dc.ColumnName);
                valueOfSelect.AppendFormat("<td><xsl:value-of select='{0}'/></td>", dc.ColumnName);
            }

            // {2} - catalog/cd
            string path = null;
            if (dtData.DataSet != null)
                path = string.Format("{0}/{1}", dtData.DataSet.DataSetName, dtData.TableName);
            else
                path = string.Format("{0}/{1}", "DocumentElement", dtData.TableName);

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat(template, reportHeader, cols.ToString(), path, valueOfSelect.ToString());

            string xslt = sb.ToString();


            // Generate Xml
            string xml = null;
            using (StringWriter sw = new StringWriter())
            {
                dtData.WriteXml(sw, XmlWriteMode.IgnoreSchema);
                xml = sw.ToString();
            }


            // Generate Word
            StringReader srXslt = null;
            StringReader srXml = null;
            try
            {
                srXslt = new StringReader(xslt);
                srXml = new StringReader(xml);

                XmlReader readerXslt = XmlReader.Create(srXslt);
                XmlReader readerXml = XmlReader.Create(srXml);

                return GetWord(readerXml, readerXslt);
            }
            finally
            {
                srXslt.Dispose();
                srXml.Dispose();
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
If you liked this article, consider reading other articles by me. For republishing article on other websites, please contact me by leaving a comment.

Comments and Discussions