コード例 #1
0
        private static void DoMailMerge(WordOpenXmlDocument document, DataTable data, IEnumerable <MailMergeMapping> mappings)
        {
            var bodyElements = document.Body.ChildElements;
            var tempBody     = new Body(document.Body.OuterXml);

            //Remove original elements:
            while (bodyElements.Count() > 0)
            {
                bodyElements.ElementAt(0).Remove();
            }

            bool firstIteration = true;

            foreach (DataRow row in data.Rows)
            {
                var newBody = new Body(tempBody.OuterXml);

                var mapValues = new Dictionary <string, string>();
                mappings.ForEach(kv =>
                {
                    if (!mapValues.ContainsKey(kv.MailMergeFieldName))
                    {
                        mapValues.Add(kv.MailMergeFieldName, row.Field <string>(kv.DataColumnFieldName));
                    }
                });

                MailMergeHelper.ProcessBody(document, newBody, null, mapValues);

                if (firstIteration)
                {
                    firstIteration = false;
                }
                else
                {
                    document.InsertPageBreak();
                }

                newBody.ChildElements.ForEach(e => document.Body.AppendChild(e.CloneNode(true)));
            }

            document.Save();
        }
コード例 #2
0
        public static WordOpenXmlDocument Create(string filePath)
        {
            var word = new WordOpenXmlDocument();

            word.Document = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document);

            var mainDocumentPart = word.Document.AddMainDocumentPart();

            const string docXml =
                @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<w:document xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
   <w:body>
   </w:body>
</w:document>";

            using (var stream = mainDocumentPart.GetStream())
            {
                byte[] buffer = (new UTF8Encoding()).GetBytes(docXml);
                stream.Write(buffer, 0, buffer.Length);
            }

            return(word);
        }
コード例 #3
0
        public static void ProcessHeadersAndFooters(WordOpenXmlDocument document, IDictionary <string, string> values)
        {
            // process header(s)
            foreach (var headerPart in document.Document.MainDocumentPart.HeaderParts)
            {
                //  2010/08/01: addition
                ConvertComplexFieldsToSimpleFields(headerPart.Header);

                FillWordFieldsInElement(values, headerPart.Header);
                headerPart.Header.Save();    // save header back in package
            }

            // process footer(s)
            foreach (var footerPart in document.Document.MainDocumentPart.FooterParts)
            {
                //  2010/08/01: addition
                ConvertComplexFieldsToSimpleFields(footerPart.Footer);

                FillWordFieldsInElement(values, footerPart.Footer);
                footerPart.Footer.Save();    // save footer back in package
            }

            document.Save();
        }
コード例 #4
0
        /// <summary>
        /// Fills in the body element with the provided data.
        /// </summary>
        /// <param name="dataSet">Dataset with the datatables to use to fill the document tables with.  Table names in the dataset should match the table names in the document.</param>
        /// <param name="values">Values to fill the document.  Keys should match the MERGEFIELD names.</param>
        /// <returns>The filled-in document.</returns>
        public static void ProcessBody(WordOpenXmlDocument document, Body body, DataSet dataSet, IDictionary <string, string> values)
        {
            ConvertComplexFieldsToSimpleFields(body);

            #region Process All Tables

            string[] switches = null;
            foreach (var field in body.Descendants <SimpleField>())
            {
                string fieldName = GetFieldName(field, out switches);
                if (!string.IsNullOrEmpty(fieldName) && fieldName.StartsWith("TBL_"))
                {
                    var tableRow = GetFirstParent <TableRow>(field);
                    if (tableRow == null)
                    {
                        // can happen because table contains multiple fields, and after 1 pass, the initial row is already deleted
                        continue;
                    }

                    var table = GetFirstParent <Table>(tableRow);
                    if (table == null)
                    {
                        // can happen because table contains multiple fields, and after 1 pass, the initial row is already deleted
                        continue;
                    }

                    string tableName = GetTableNameFromFieldName(fieldName);

                    if (dataSet == null || !dataSet.Tables.Contains(tableName) || dataSet.Tables[tableName].Rows.Count == 0)
                    {
                        // don't remove table here: will be done in next pass
                        continue;
                    }

                    var dataTable = dataSet.Tables[tableName];

                    var cellPropertiesList      = new List <TableCellProperties>();
                    var cellColumnNamesList     = new List <string>();
                    var paragraphPropertiesList = new List <string>();
                    var cellFieldsList          = new List <SimpleField>();

                    foreach (var tableCell in tableRow.Descendants <TableCell>())
                    {
                        cellPropertiesList.Add(tableCell.GetFirstChild <TableCellProperties>());
                        var paragraph = tableCell.GetFirstChild <Paragraph>();
                        if (paragraph != null)
                        {
                            var pp = paragraph.GetFirstChild <ParagraphProperties>();
                            if (pp != null)
                            {
                                paragraphPropertiesList.Add(pp.OuterXml);
                            }
                            else
                            {
                                paragraphPropertiesList.Add(null);
                            }
                        }
                        else
                        {
                            paragraphPropertiesList.Add(null);
                        }

                        string      columnName  = string.Empty;
                        SimpleField columnField = null;
                        foreach (var cellField in tableCell.Descendants <SimpleField>())
                        {
                            columnField = cellField;
                            columnName  = GetColumnNameFromFieldName(GetFieldName(cellField, out switches));
                            break;  // supports only 1 cellfield per table
                        }

                        cellColumnNamesList.Add(columnName);
                        cellFieldsList.Add(columnField);
                    }

                    // keep reference to row properties
                    var rowProperties = tableRow.GetFirstChild <TableRowProperties>();

                    foreach (DataRow dataRow in dataTable.Rows)
                    {
                        var row = new TableRow();

                        if (rowProperties != null)
                        {
                            row.Append(new TableRowProperties(rowProperties.OuterXml));
                        }

                        for (int i = 0; i < cellPropertiesList.Count; i++)
                        {
                            var cellProperties = new TableCellProperties(cellPropertiesList[i].OuterXml);
                            var cell           = new TableCell();
                            cell.Append(cellProperties);
                            var p = new Paragraph(new ParagraphProperties(paragraphPropertiesList[i]));
                            cell.Append(p);   // cell must contain at minimum a paragraph !

                            if (!string.IsNullOrEmpty(cellColumnNamesList[i]))
                            {
                                if (!dataTable.Columns.Contains(cellColumnNamesList[i]))
                                {
                                    throw new Exception(string.Format("Unable to complete template: column name '{0}' is unknown in parameter tables !", cellColumnNamesList[i]));
                                }

                                if (!dataRow.IsNull(cellColumnNamesList[i]))
                                {
                                    string val = dataRow[cellColumnNamesList[i]].ToString();
                                    p.Append(GetRunElementForText(val, cellFieldsList[i]));
                                }
                            }
                            row.Append(cell);
                        }
                        table.Append(row);
                    }

                    // finally : delete template-row (and thus also the mergefields in the table)
                    tableRow.Remove();
                }
            }

            #endregion Process All Tables

            #region Clean Empty Tables

            foreach (var field in body.Descendants <SimpleField>())
            {
                string fieldName = GetFieldName(field, out switches);
                if (!string.IsNullOrEmpty(fieldName) && fieldName.StartsWith("TBL_"))
                {
                    var tableRow = GetFirstParent <TableRow>(field);
                    if (tableRow == null)
                    {
                        continue;   // can happen: is because table contains multiple fields, and after 1 pass, the initial row is already deleted
                    }

                    var table = GetFirstParent <Table>(tableRow);
                    if (table == null)
                    {
                        continue;   // can happen: is because table contains multiple fields, and after 1 pass, the initial row is already deleted
                    }

                    string tableName = GetTableNameFromFieldName(fieldName);
                    if (dataSet == null || !dataSet.Tables.Contains(tableName) || dataSet.Tables[tableName].Rows.Count == 0)
                    {
                        // if there's a 'dt' switch: delete Word-table
                        if (switches.Contains("dt"))
                        {
                            table.Remove();
                        }
                    }
                }
            }

            #endregion Clean Empty Tables

            #region Process Remaining Fields In Main Document & Save

            FillWordFieldsInElement(values, body);
            document.Save();  // save main document back in package

            #endregion Process Remaining Fields In Main Document & Save
        }