Beispiel #1
0
        //private void AssignSectionProperties(Document document, SectionProperties secProperties)
        //{
        //    if (document == null)
        //    {
        //        throw new ArgumentNullException("document");
        //    }

        //    if (secProperties != null)
        //    {
        //        PageSize pageSize = secProperties.Descendants<PageSize>().FirstOrDefault();

        //        if (pageSize != null)
        //        {
        //            pageSize.Remove();
        //        }

        //        PageMargin pageMargin = secProperties.Descendants<PageMargin>().FirstOrDefault();

        //        if (pageMargin != null)
        //        {
        //            pageMargin.Remove();
        //        }

        //        document.AppendChild(new Paragraph(new ParagraphProperties(new SectionProperties(pageSize, pageMargin))));
        //    }
        //}

        private static Paragraph CreateParagraph(OpenXmlCompositeElement openXmlCompositeElement, List <Run> runs)
        {
            ParagraphProperties paragraphProperties = openXmlCompositeElement.Descendants <ParagraphProperties>().FirstOrDefault();
            Paragraph           para = null;

            if (paragraphProperties != null)
            {
                para = new Paragraph(paragraphProperties.CloneNode(true));
                foreach (Run run in runs)
                {
                    para.AppendChild <Run>(run);
                }
            }
            else
            {
                para = new Paragraph();
                foreach (Run run in runs)
                {
                    para.AppendChild <Run>(run);
                }
            }
            return(para);
        }
Beispiel #2
0
        /// <summary>
        /// Sets the unique content control ids.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="existingIds">The existing ids.</param>
        public static void SetUniquecontentControlIds(OpenXmlCompositeElement element, IList <int> existingIds)
        {
            var randomizer = new Random();

            foreach (var sdtId in element.Descendants <SdtId>())
            {
                if (existingIds.Contains(sdtId.Val))
                {
                    var randomId = randomizer.Next(int.MaxValue);

                    while (existingIds.Contains(randomId))
                    {
                        randomizer.Next(int.MaxValue);
                    }

                    sdtId.Val.Value = randomId;
                }
                else
                {
                    existingIds.Add(sdtId.Val);
                }
            }
        }
Beispiel #3
0
        private static Text SetTextElement(OpenXmlCompositeElement elem, string name, string text)
        {
            var textElems = elem.Descendants <Text>();

            textElems.Skip(1).ToList().ForEach(e => e.Remove());

            var textElem = textElems.FirstOrDefault();

            if (textElem == null && elem.ChildElements.Count > 0)
            {
                throw new InvalidOperationException($"[{name}] No text element: {string.Join(", ", elem.ChildElements.Select(o => o.GetType()))}");
            }
            if (textElem == null)
            {
                textElem = new Text();
                elem.Append(
                    new Paragraph(
                        new Run(
                            //new RunProperties() { Languages = new Languages() { Val = "el-GR" } },
                            textElem)));
            }
            textElem.Text = text;
            return(textElem);
        }
        /// <summary>
        /// Sets the unique content control ids.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="existingIds">The existing ids.</param>
        public static void SetUniquecontentControlIds(OpenXmlCompositeElement element, IList<int> existingIds)
        {
            var randomizer = new Random();

            foreach (var sdtId in element.Descendants<SdtId>())
            {
                if (existingIds.Contains(sdtId.Val))
                {
                    var randomId = randomizer.Next(int.MaxValue);

                    while (existingIds.Contains(randomId))
                    {
                        randomizer.Next(int.MaxValue);
                    }

                    sdtId.Val.Value = randomId;
                }
                else
                {
                    existingIds.Add(sdtId.Val);
                }
            }
        }
Beispiel #5
0
 /// <summary>
 /// Determines whether element is placeholder.
 /// </summary>
 /// <param name="xmlCompositeElement"></param>
 /// <returns></returns>
 public static bool IsPlaceholder(this OpenXmlCompositeElement xmlCompositeElement)
 {
     return(xmlCompositeElement.Descendants <P.PlaceholderShape>().Any());
 }
Beispiel #6
0
 /// <summary>
 /// Determines whether element is table.
 /// </summary>
 /// <param name="compositeElement"></param>
 public static bool IsTable(this OpenXmlCompositeElement compositeElement)
 {
     return(compositeElement.Descendants <D.Table>().Any());
 }
Beispiel #7
0
        /// <summary>
        /// Sets the SDT content keeping permission elements.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="newChildren">The new children.</param>
        private void SetSdtContentKeepingPermissionElements(OpenXmlCompositeElement openXmlCompositeElement, List<OpenXmlElement> newChildren)
        {
            PermStart start = openXmlCompositeElement.Descendants<PermStart>().FirstOrDefault();
            PermEnd end = openXmlCompositeElement.Descendants<PermEnd>().FirstOrDefault();
            openXmlCompositeElement.RemoveAllChildren();

            if (start != null)
            {
                openXmlCompositeElement.AppendChild(start);
            }

            foreach (var newChild in newChildren)
            {
                openXmlCompositeElement.AppendChild(newChild);
            }

            if (end != null)
            {
                openXmlCompositeElement.AppendChild(end);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Creates the run.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="content">The content.</param>
        /// <returns></returns>
        private static Run CreateRun(OpenXmlCompositeElement openXmlCompositeElement, string content)
        {
            RunProperties runProperties = openXmlCompositeElement.Descendants<RunProperties>().FirstOrDefault();
            Run run = null;

            if (runProperties != null)
            {
                run = new Run(runProperties.CloneNode(true), new Text(content));
            }
            else
            {
                run = new Run(new Text(content));
            }

            return run;
        }
        /// <summary>
        /// Updates the category value chart series.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="newSeriesIndex">New index of the series.</param>
        /// <param name="categoryHeadingRange">The category heading range.</param>
        /// <param name="axisDataRange">The axis data range.</param>
        /// <param name="seriesDataRange">The series data range.</param>
        /// <exception cref="ArgumentNullException">series</exception>
        /// <exception cref="InvalidOperationException">Only valid for series of type BarChartSeries, LineChartSeries, AreaChartSeries & PieChartSeries</exception>
        public static void UpdateCategoryValueChartSeries(this OpenXmlCompositeElement series,
                                                          uint newSeriesIndex,
                                                          CompositeRangeReference categoryHeadingRange,
                                                          CompositeRangeReference axisDataRange,
                                                          CompositeRangeReference seriesDataRange)
        {
            if (series == null)
            {
                throw new ArgumentNullException("series");
            }

            if (!(series is BarChartSeries) && !(series is LineChartSeries) && !(series is AreaChartSeries) && !(series is PieChartSeries))
            {
                throw new InvalidOperationException("Only valid for series of type BarChartSeries, LineChartSeries, AreaChartSeries & PieChartSeries");
            }

            // Updates the supplied series Index and Order
            var index = series.Descendants <Index>().FirstOrDefault();

            if (index != null)
            {
                index.Val = (UInt32Value)newSeriesIndex;
            }

            var order = series.Descendants <Order>().FirstOrDefault();

            if (order != null)
            {
                order.Val = (UInt32Value)newSeriesIndex;
            }

            // Set the formula on the SeriesText ('Legend Entries(Series)' in Excel).
            // This is set to reference the column header in Excel and determines the Category Heading
            var seriesText = series.Descendants <SeriesText>().FirstOrDefault();

            if (seriesText != null)
            {
                seriesText.StringReference              = new StringReference();
                seriesText.StringReference.Formula      = new Formula();
                seriesText.StringReference.Formula.Text = categoryHeadingRange.Reference;
            }

            // Set the formula on the Category Axis
            var categoryAxisData = series.Descendants <CategoryAxisData>().FirstOrDefault();

            if (categoryAxisData != null)
            {
                categoryAxisData.StringReference              = new StringReference();
                categoryAxisData.StringReference.Formula      = new Formula();
                categoryAxisData.StringReference.Formula.Text = axisDataRange.Reference;
            }

            // Set the Formula on the data
            var values = series.Descendants <Values>().FirstOrDefault();

            if (values != null)
            {
                values.NumberReference              = new NumberReference();
                values.NumberReference.Formula      = new Formula();
                values.NumberReference.Formula.Text = seriesDataRange.Reference;
            }
        }
        /// <summary>
        /// Sets the SDT content keeping permission elements.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="newChildren">The new children.</param>
        private static void SetSdtContentKeepingPermissionElements(OpenXmlCompositeElement openXmlCompositeElement, IEnumerable<Run> newChildren)
        {
            var start = openXmlCompositeElement.Descendants<PermStart>().FirstOrDefault();
            var end = openXmlCompositeElement.Descendants<PermEnd>().FirstOrDefault();
            openXmlCompositeElement.RemoveAllChildren();

            if (start != null)
            {
                openXmlCompositeElement.AppendChild(start);
            }

            foreach (var newChild in newChildren)
            {
                openXmlCompositeElement.AppendChild(newChild);
            }

            if (end != null)
            {
                openXmlCompositeElement.AppendChild(end);
            }
        }
Beispiel #11
0
 public NonPlaceholderTransform(OpenXmlCompositeElement xmlElement)
 {
     _offset  = xmlElement.Descendants <DocumentFormat.OpenXml.Drawing.Offset>().First(); //TODO: make lazy
     _extents = xmlElement.Descendants <DocumentFormat.OpenXml.Drawing.Extents>().First();
 }
        /// <summary>
        /// Processes the dynamic chart.
        /// </summary>
        /// <param name="tableDataSheetName">Name of the table data sheet.</param>
        /// <param name="tableData">The table data.</param>
        /// <param name="chartModel">The chart model.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">chartModel</exception>
        private static bool ProcessDynamicChart(string tableDataSheetName, TableData tableData, ChartModel chartModel)
        {
            if (chartModel == null)
            {
                throw new ArgumentNullException("chartModel");
            }

            TempDiagnostics.Output(string.Format("Processing chart in sheet '{0}'", tableDataSheetName));

            var seriesFactory = new SeriesFactory(chartModel);

            if (seriesFactory.SourceSeriesCount > 0)
            {
                if (tableData.TreatRowAsSeries == false)
                {
                    // A COLUMN of data represents a series...
                    // Find the Range that representes the first Axis Data for all of the series...
                    CompositeRangeReference category1AxisRange = DetermineCategory1AxisRange(tableData, tableData.TreatRowAsSeries, tableDataSheetName);

                    foreach (TableColumn column in tableData.Columns)
                    {
                        // Skip if we are on the category column
                        if (column.DataRegion.ExcelColumnStart == category1AxisRange.MinColumnIndex)
                        {
                            continue;
                        }

                        // Get information about the series that will be based on the column
                        var seriesInfo = new ChartSeriesInfo(column);

                        // We need a column that has not been actively excluded
                        if (seriesInfo.BaseOnChartSeriesIndex >= 0 && !seriesInfo.SuppressSeries)
                        {
                            // Get the template series or get a copy if already used
                            OpenXmlCompositeElement clonedSeries = seriesFactory.GetOrCloneSourceSeries(seriesInfo.BaseOnChartSeriesIndex);

                            //TODO: Allow ability to assign colour palettes (as opposed to colours) to dynamically generated series
                            Color?seriesColour = seriesInfo.SeriesColour;
                            if (!seriesColour.HasValue)
                            {
                                int useCount = seriesFactory.GetUseCount(seriesInfo.BaseOnChartSeriesIndex);
                                seriesColour = new Color?((ColourPalette.GetColour(ColourPaletteType.GamTechnicalChartPalette, useCount - 1)));
                            }

                            var seriesTextRange = new CompositeRangeReference(new RangeReference(tableDataSheetName,
                                                                                                 (uint)column.DataRegion.ExcelRowStart,
                                                                                                 (uint)column.DataRegion.ExcelColumnStart));



                            // Series data is first column only
                            var seriesValuesRange = new CompositeRangeReference(new RangeReference(tableDataSheetName,
                                                                                                   (uint)column.DataRegion.ExcelRowStart + 1,
                                                                                                   (uint)column.DataRegion.ExcelColumnStart,
                                                                                                   (uint)column.DataRegion.ExcelRowEnd,
                                                                                                   (uint)column.DataRegion.ExcelColumnStart));

                            // Determine data ranges to be used within chart series.
                            ChartDataRangeInfo dataRangeInfo = new ChartDataRangeInfo
                            {
                                SeriesTextRange       = seriesTextRange,
                                CategoryAxisDataRange = category1AxisRange,
                                SeriesValuesRange     = seriesValuesRange,
                            };

                            // update all formula on the series
                            UpdateChartSeriesDataReferences(clonedSeries, dataRangeInfo, new SolidColorBrush(seriesColour.Value));
                        }
                    }
                }
                else
                {
                    // A ROW of data represents a series...
                    // Find the Range that representes the first Axis Data for all of the series...
                    CompositeRangeReference category1AxisRange = DetermineCategory1AxisRange(tableData, tableData.TreatRowAsSeries, tableDataSheetName);
                    TableColumn             seriesTextColumn   = tableData.Columns[FindNonExcludedColumnIndex(tableData, 1)];

                    // Build a list of columns to include in the series
                    var seriesTableColumns = new List <TableColumn>();

                    int         seriesValuesColumnIndex = FindNonExcludedColumnIndex(tableData, 2);
                    TableColumn firstSeriesValuesColumn = tableData.Columns[seriesValuesColumnIndex];
                    seriesTableColumns.Add(firstSeriesValuesColumn);

                    // Count up to last column, excluding those marked for exclusion
                    while (seriesValuesColumnIndex < (tableData.Columns.Count - 1))
                    {
                        seriesValuesColumnIndex++;
                        TableColumn tableColumn = tableData.Columns[seriesValuesColumnIndex];

                        ChartExcludeOption excludeOption = tableColumn.ChartOptions.GetOptionOrDefault <ChartExcludeOption>();
                        if (excludeOption == null || excludeOption.Exclude == false)
                        {
                            seriesTableColumns.Add(tableColumn);
                        }
                    }

                    foreach (TableDataRowInfo rowInfo in tableData.RowData)
                    {
                        // Extract chart series related properties from row data
                        var seriesInfo = new ChartSeriesInfo(rowInfo.RowData);

                        // Determine where data has been written into Excel
                        uint rowIndex = (uint)tableData.MapContainer.ExcelRowStart + rowInfo.TableRowIndex - 1;

                        // Skip if we are on the category column
                        if (rowIndex == category1AxisRange.MinRowIndex)
                        {
                            continue;
                        }

                        // We need a column that has not been actively excluded
                        if (seriesInfo.BaseOnChartSeriesIndex >= 0 && !seriesInfo.SuppressSeries)
                        {
                            // Get the template series or get a copy if already used
                            OpenXmlCompositeElement clonedSeries = seriesFactory.GetOrCloneSourceSeries(seriesInfo.BaseOnChartSeriesIndex);

                            //TODO: Allow ability to assign colour palettes (as opposed to colours) to dynamically generated series
                            Color?seriesColour = seriesInfo.SeriesColour;
                            if (!seriesColour.HasValue)
                            {
                                int useCount = seriesFactory.GetUseCount(seriesInfo.BaseOnChartSeriesIndex);
                                seriesColour = new Color?((ColourPalette.GetColour(ColourPaletteType.GamTechnicalChartPalette, useCount - 1)));
                            }

                            // SeriesText is the series heading used in legends
                            var seriesTextRange = new CompositeRangeReference(new RangeReference(tableDataSheetName,
                                                                                                 rowIndex,
                                                                                                 (uint)seriesTextColumn.DataRegion.ExcelColumnStart));

                            // From column after category to last column in table.
                            var seriesValuesRange = new CompositeRangeReference();
                            foreach (TableColumn tableColumn in seriesTableColumns)
                            {
                                seriesValuesRange.Update(tableDataSheetName,
                                                         rowIndex,
                                                         (uint)tableColumn.DataRegion.ExcelColumnStart,
                                                         rowIndex,
                                                         (uint)tableColumn.DataRegion.ExcelColumnStart);
                            }

                            // Determine data ranges to be used within chart series.
                            ChartDataRangeInfo dataRangeInfo = new ChartDataRangeInfo
                            {
                                SeriesTextRange       = seriesTextRange,
                                CategoryAxisDataRange = category1AxisRange,
                                SeriesValuesRange     = seriesValuesRange,
                            };

                            // update all formula on the series ( I know we're constantly swapping between brush and color here.... Address later)
                            UpdateChartSeriesDataReferences(clonedSeries, dataRangeInfo, new SolidColorBrush(seriesColour.Value));
                        }
                    }
                }

                // Remove all un-used template series and set the order of remaining.
                uint seriesIndex = 0;
                for (int idx = 0; idx < seriesFactory.SourceSeriesCount; idx++)
                {
                    OpenXmlCompositeElement templateSeries = seriesFactory.GetSourceSeriesElement(idx);

                    // Value is the use-count, if zero then the template needs removing.
                    if (seriesFactory.GetUseCount(idx) == 0)
                    {
                        // Remove the template series.
                        templateSeries.Remove();
                    }
                    else
                    {
                        // Set template series index and order to initial value, then set clones
                        var templateIndex = templateSeries.Descendants <DrawingCharts.Index>().FirstOrDefault();
                        if (templateIndex != null)
                        {
                            templateIndex.Val = seriesIndex;
                        }

                        var templateOrder = templateSeries.Descendants <DrawingCharts.Order>().FirstOrDefault();
                        if (templateOrder != null)
                        {
                            templateOrder.Val = seriesIndex;
                        }

                        seriesIndex++;

                        OpenXmlElement lastElement = templateSeries;

                        foreach (var clonedElement in seriesFactory.GetClonedSeriesElements(idx))
                        {
                            var index = clonedElement.Descendants <DrawingCharts.Index>().FirstOrDefault();
                            if (index != null)
                            {
                                index.Val = seriesIndex;
                            }

                            var order = clonedElement.Descendants <DrawingCharts.Order>().FirstOrDefault();
                            if (order != null)
                            {
                                order.Val = seriesIndex;
                            }

                            lastElement.InsertAfterSelf <OpenXmlElement>(clonedElement);
                            lastElement = clonedElement;
                            seriesIndex++;
                        }
                    }
                }
            }

            return(true);
        }
 public NonPlaceholderTransform(OpenXmlCompositeElement sdkCompositeElement)
 {
     _offset  = sdkCompositeElement.Descendants <A.Offset>().First();
     _extents = sdkCompositeElement.Descendants <A.Extents>().First();
 }
        public static void UpdateCategoryValueChartSeries(this OpenXmlCompositeElement series,
                                                          bool isRowSeries,
                                                          string sheetName,
                                                          uint seriesCount,
                                                          uint itemPosition,
                                                          uint xCount,
                                                          uint xOffset,
                                                          uint yCount,
                                                          uint yOffset)
        {
            if (series == null)
            {
                throw new ArgumentNullException("series");
            }

            if (!(series is BarChartSeries) && !(series is LineChartSeries))
            {
                throw new InvalidOperationException("Only valid for series of type BarChartSeries & LineChartSeries");
            }

            // Updates the supplied series Index and Order
            var index = series.Descendants <Index>().FirstOrDefault();

            if (index != null)
            {
                index.Val = (UInt32Value)seriesCount;
            }

            var order = series.Descendants <Order>().FirstOrDefault();

            if (order != null)
            {
                order.Val = (UInt32Value)seriesCount;
            }

            // Set the SeriesText ('Legend Entries(Series)' in Excel).
            // This is set to reference the column header in Excel and determines the Category.
            var seriesText = series.Descendants <SeriesText>().FirstOrDefault();

            if (seriesText != null)
            {
                seriesText.StringReference         = new StringReference();
                seriesText.StringReference.Formula = new Formula();

                if (isRowSeries)
                {
                    seriesText.StringReference.Formula.Text = string.Format("'{0}'!$A${1}", sheetName, itemPosition + 1);
                }
                else
                {
                    // a column is a series
                    seriesText.StringReference.Formula.Text = string.Format("'{0}'!${1}${2}", sheetName, CellExtensions.GetColumnLetter(itemPosition + 1), yOffset);
                }
            }

            // set the formula for the category axis, currently always the 1st column of data
            var categoryAxisData = series.Descendants <CategoryAxisData>().FirstOrDefault();

            if (categoryAxisData != null)
            {
                categoryAxisData.StringReference         = new StringReference();
                categoryAxisData.StringReference.Formula = new Formula();
                if (isRowSeries)
                {
                    // if row is the series, the category are the dynamic columns
                    // so for example B3:F3
                    categoryAxisData.StringReference.Formula.Text = string.Format("'{0}'!${1}${2}:${3}${2}", sheetName, CellExtensions.GetColumnLetter(xOffset + 1), yOffset, CellExtensions.GetColumnLetter(xCount + 1));
                }
                else
                {
                    // if row isnt series, then its a category, the default behaviour
                    // so assuming 1st column is the category then formula is A4:A10 with 4 being the starting row in the sheet
                    categoryAxisData.StringReference.Formula.Text = string.Format("'{0}'!$A${1}:$A${2}", sheetName, yOffset + 1, yCount + yOffset);
                }
            }

            var values = series.Descendants <Values>().FirstOrDefault();

            if (values != null)
            {
                values.NumberReference         = new NumberReference();
                values.NumberReference.Formula = new Formula();
                if (isRowSeries)
                {
                    values.NumberReference.Formula.Text = string.Format("'{0}'!${1}${2}:${3}${2}", sheetName, CellExtensions.GetColumnLetter(xOffset + 1), itemPosition + 1, CellExtensions.GetColumnLetter(xCount + xOffset));
                }
                else
                {
                    values.NumberReference.Formula.Text = string.Format("'{0}'!${1}${2}:${1}${3}", sheetName, CellExtensions.GetColumnLetter(itemPosition + 1), yOffset + 1, yCount + yOffset);
                }
            }
        }
        /// <summary>
        /// Creates the paragraph.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="runs">The runs.</param>
        /// <returns>Returns the paragraph element</returns>
        private static Paragraph CreateParagraph(OpenXmlCompositeElement openXmlCompositeElement, List<Run> runs)
        {
            var paragraphProperties = openXmlCompositeElement.Descendants<ParagraphProperties>().FirstOrDefault();
            Paragraph para;

            if (paragraphProperties != null)
            {
                para = new Paragraph(paragraphProperties.CloneNode(true));
                foreach (var run in runs)
                {
                    para.AppendChild(run);
                }
            }
            else
            {
                para = new Paragraph();
                foreach (var run in runs)
                {
                    para.AppendChild(run);
                }
            }

            return para;
        }
        /// <summary>
        /// Creates the run.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="content">The content.</param>
        /// <returns>Returns a run object</returns>
        private static Run CreateRun(OpenXmlCompositeElement openXmlCompositeElement, string content)
        {
            var runProperties = openXmlCompositeElement.Descendants<RunProperties>().FirstOrDefault();

            var run = runProperties != null
                          ? new Run(runProperties.CloneNode(true), new Text(content))
                          : new Run(new Text(content));

            return run;
        }
Beispiel #17
0
        /// <summary>
        /// Creates the run.
        /// </summary>
        /// <param name="openXmlCompositeElement">The open XML composite element.</param>
        /// <param name="content">The content.</param>
        /// <returns></returns>
        private static Run CreateRun(OpenXmlCompositeElement openXmlCompositeElement, string content)
        {
            RunProperties runProperties = openXmlCompositeElement.Descendants <RunProperties>().FirstOrDefault();

            return(runProperties != null ? new Run(runProperties.CloneNode(true), new Text(content)) : new Run(new Text(content)));
        }
Beispiel #18
0
        /// <summary>
        /// Finds and replaces text in the target element
        /// </summary>
        /// <param name="element">Target element</param>
        /// <param name="find">Text to find and replace</param>
        /// <param name="replaceWith">Text to replace with</param>
        private static void ReplaceText(OpenXmlCompositeElement element, string find, string replaceWith)
        {
            if (find.IsNullOrEmptyOrWhiteSpace())
            {
                return;
            }

            if (replaceWith == null)
            {
                replaceWith = string.Empty;
            }

            var texts = element.Descendants <Text>();

            for (var t = 0; t < texts.Count(); t++)
            {
                var txt = texts.ElementAt(t);

                for (var c = 0; c < txt.Text.Length; c++)
                {
                    var match = IsMatch(texts, t, c, find);

                    if (match != null)
                    {
                        // now replace the text
                        var lines = replaceWith.Replace(Environment.NewLine, "\r")
                                    .Split('\n', '\r');

                        var skip = lines[lines.Length - 1].Length - 1;

                        if (c > 0)
                        {
                            lines[0] = txt.Text.Substring(0, c) + lines[0];
                        }

                        if (match.EndCharIndex + 1 < texts.ElementAt(match.EndElementIndex).Text.Length)
                        {
                            lines[lines.Length - 1] = lines[lines.Length - 1] + texts.ElementAt(match.EndElementIndex)
                                                      .Text.Substring(match.EndCharIndex + 1);
                        }

                        txt.Space = new EnumValue <SpaceProcessingModeValues>(SpaceProcessingModeValues
                                                                              .Preserve);

                        txt.Text = lines[0];

                        for (var i = t + 1; i <= match.EndElementIndex; i++)
                        {
                            texts.ElementAt(i).Text = string.Empty;
                        }

                        if (replaceWith.IsNullOrEmptyOrWhiteSpace())
                        {
                            txt.Parent.Parent.Remove();
                        }

                        if (lines.Count() > 1)
                        {
                            OpenXmlElement currEl              = txt;
                            var            run                 = currEl.Parent as Run;
                            var            sampleRun           = (Run)run.Clone();
                            var            sampleRunProperties = (RunProperties)sampleRun.GetFirstChild <RunProperties>().Clone();
                            var            sampleTxt           = (Text)sampleRun.GetFirstChild <Text>().Clone();
                            var            paragraph           = run.Parent as Paragraph;
                            var            sampleParagraph     = (Paragraph)paragraph.Clone();
                            sampleParagraph.RemoveAllChildren <Run>();
                            currEl = paragraph;

                            for (var i = 1; i < lines.Count(); i++)
                            {
                                var paragraphBefore  = currEl;
                                var paragraphAfter   = (Paragraph)sampleParagraph.Clone();
                                var newRun           = new Run();
                                var newRunProperties = (RunProperties)sampleRunProperties.Clone();
                                var newTxt           = (Text)sampleTxt.Clone();
                                newTxt.Space = SpaceProcessingModeValues.Preserve;
                                newTxt.Text  = lines[i];
                                paragraphAfter.InsertAfter(newRun, paragraphAfter.LastChild);
                                newRun.InsertAt(newRunProperties, 0);
                                newRun.InsertAt(newTxt, 1);
                                paragraphBefore.InsertAfterSelf(paragraphAfter);
                                currEl = paragraphAfter;
                            }

                            c = skip;
                        }
                        else
                        {
                            c += skip;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Sets the color of the series using a solidcolor brush
        /// If a null brush is supplied any color is removed so the color will be automatic
        /// </summary>
        /// <param name="line">The line.</param>
        /// <param name="brush">The brush.</param>
        public static void UpdateLineBrush(this OpenXmlCompositeElement line, Brush brush)
        {
            if (line == null)
            {
                return;
            }

            // If we have a BarChart, we really want tp update the SolidFill (not the Outline.SolidFill)
            BarChartSeries barChartSeries = line as BarChartSeries;

            if (barChartSeries != null)
            {
                // For BarCharts, we update the SolidFill
                barChartSeries.UpdateSeriesColour((SolidColorBrush)brush);
            }
            else
            {
                // Update the Outline.SolidFill + set the SolidFill to the same colour
                var chartShapeProperties = line.Descendants <ChartShapeProperties>().FirstOrDefault();

                if (brush == null && !(brush is SolidColorBrush))
                {
                    if (chartShapeProperties != null)
                    {
                        line.RemoveChild <ChartShapeProperties>(chartShapeProperties);
                    }
                    return;
                }

                // the series title, this is the name of the column header
                var seriesText = line.Descendants <SeriesText>().FirstOrDefault();

                if (chartShapeProperties == null)
                {
                    chartShapeProperties = new ChartShapeProperties();
                    // if there's a series text then insert afterwards
                    if (seriesText == null)
                    {
                        line.InsertAt <ChartShapeProperties>(chartShapeProperties, 0);
                    }
                    else
                    {
                        line.InsertAfter <ChartShapeProperties>(chartShapeProperties, seriesText);
                    }
                }

                var outline = chartShapeProperties.Descendants <Outline>().FirstOrDefault();
                if (outline == null)
                {
                    outline = new Outline();
                    chartShapeProperties.InsertAt(outline, 0);
                }

                var outlineSolidFill = outline.Descendants <SolidFill>().FirstOrDefault();
                if (outlineSolidFill == null)
                {
                    outlineSolidFill = new SolidFill();
                    outline.Append(outlineSolidFill);
                }

                // Update the fill with the supplied brush colour
                outlineSolidFill.UpdateSolidFill((SolidColorBrush)brush);

                // Clones the OutlineSolidFill as the SolidFill of the series...
                var solidFill = chartShapeProperties.GetFirstChild <SolidFill>();
                if (solidFill != null)
                {
                    chartShapeProperties.RemoveChild(solidFill);
                }
                chartShapeProperties.InsertAt(outlineSolidFill.CloneNode(true), 0);
            }
        }