Beispiel #1
0
        private static void UpdateCachedValues(ReportData conf, OpenXmlPart chartPart, SpreadsheetDocument spreadsheetDoc, TableDefinition content)
        {
            try
            {
                var chartDoc = chartPart.GetXDocument();

                // We update the cached value now
                XElement chartCached = chartDoc.Descendants(C.chart).FirstOrDefault();
                if (null != chartCached)
                {
                    // We look for Chart Title -----------------------------------------------
                    var titleElement = chartCached.Descendants(C.title).FirstOrDefault();
                    if (titleElement == null) // No title so we need to enforce no will be displayed when regenerating Cached Values
                    {
                        var autoTitleDeleted = chartCached.Descendants(C.autoTitleDeleted).FirstOrDefault();
                        if (autoTitleDeleted == null)
                        {
                            autoTitleDeleted = new XElement(C.autoTitleDeleted);
                            chartCached.Add(autoTitleDeleted);
                        }
                        autoTitleDeleted.SetAttributeValue(NoNamespace.val, "1");
                    }
                    // ----------------------------------------------------------------------


                    // Series in Graph ------------------------------------------------------
                    List <XElement> cSerie         = chartCached.Descendants(C.ser).ToList();
                    var             formulaToCheck = new List <XElement>();
                    int             cSerieCount    = cSerie.Count;
                    for (int ctSer = 0; ctSer < cSerieCount; ctSer += 1)
                    {
                        #region Serie Treatment
                        var oneSerie = cSerie[ctSer];

                        // We check if the content as been given for this serie
                        formulaToCheck.Clear();
                        formulaToCheck.AddRange(oneSerie.Descendants(C.numRef).Descendants(C.f).Union(oneSerie.Descendants(C.strRef).Descendants(C.f)));

                        bool isSerieDeleted = false;
                        foreach (var oneFormula in formulaToCheck)
                        {
                            int    startRow;
                            int    startCol;
                            int    endRow;
                            int    endCol;
                            string sheetName = WorksheetAccessorExt.GetFormulaCoord(oneFormula.Value, out startRow, out startCol, out endRow, out endCol);
                            if ((startRow > content.NbRows && endRow > content.NbRows) ||
                                (startCol > content.NbColumns && endCol > content.NbColumns))
                            {
                                // We need to remove the whole serie as it is out of scope
                                isSerieDeleted = true;
                                oneSerie.Remove();
                                break;
                            }
                            // ignore if mapped to a single cell of first row or first column
                            if ((endCol - startCol == 0 && endRow - startRow == 0) && (startCol == 1 || startRow == 1))
                            {
                                continue;
                            }
                            // otherwise this is mapped to a range: update
                            if (startCol == endCol && endRow != content.NbRows && startRow != endRow)
                            {
                                endRow           = content.NbRows; // -startRow;
                                oneFormula.Value = WorksheetAccessorExt.SetFormula(sheetName, startRow, startCol, endRow, endCol);
                            }
                            if (startRow == endRow && endCol != content.NbColumns && startCol != endCol)
                            {
                                endCol           = content.NbColumns; // -startRow;
                                oneFormula.Value = WorksheetAccessorExt.SetFormula(sheetName, startRow, startCol, endRow, endCol);
                            }
                        }
                        // ------------

                        // No need to go further, the serie is deleted (or will generate error "parent is missing")
                        if (isSerieDeleted)
                        {
                            continue;
                        }

                        // We now update Cached Value
                        IEnumerable <XElement> cachedBlock = oneSerie.Descendants(C.strRef).Union(oneSerie.Descendants(C.numRef));

                        foreach (XElement oneCache in cachedBlock)
                        {
                            var formula  = oneCache.Descendants(C.f).FirstOrDefault();
                            var allCells = oneCache.Descendants(C.pt); //.ToList()

                            if (formula != null)
                            {
                                int           startRow;
                                int           startCol;
                                int           endRow;
                                int           endCol;
                                string        sheetName;
                                WorksheetPart sheet = WorksheetAccessorExt.GetFormula
                                                          (spreadsheetDoc, formula.Value
                                                          , out sheetName, out startRow
                                                          , out startCol, out endRow
                                                          , out endCol
                                                          );
                                if (sheet != null)
                                {
                                    int      indexCell    = 0;
                                    XElement previousCell = null;
                                    for (int ctRow = startRow; ctRow <= endRow; ctRow += 1)
                                    {
                                        for (int ctCol = startCol; ctCol <= endCol; ctCol += 1)
                                        {
                                            var cachedCell = allCells.FirstOrDefault(x => x.Attribute(NoNamespace.idx) != null &&
                                                                                     x.Attribute(NoNamespace.idx)?.Value == indexCell.ToString());
                                            if (cachedCell == null && previousCell != null)
                                            {
                                                cachedCell = new XElement(previousCell);
                                                cachedCell.Attribute(NoNamespace.idx).Value = indexCell.ToString();
                                                previousCell.Parent?.Add(cachedCell);
                                            }

                                            if (ctRow > content.NbRows || ctCol > content.NbColumns)
                                            {
                                                indexCell += 1;
                                                cachedCell.Remove();
                                                continue;
                                            }

                                            var cellValue = WorksheetAccessor.GetCellValue(spreadsheetDoc, sheet, ctCol, ctRow);

                                            var cachedCellValue = cachedCell.Descendants(C.v).FirstOrDefault();
                                            if (null != cachedCellValue && null != cellValue)
                                            {
                                                cachedCellValue.Value = cellValue.ToString();
                                            }
                                            else
                                            {
                                                LogHelper.Instance.LogWarn("No cell value in cached cell or no cell value in attached spreadsheet.");
                                            }

                                            indexCell   += 1;
                                            previousCell = cachedCell;
                                        }
                                    }

                                    // --------------------
                                    // We clean other IDX
                                    var maxId           = (endCol - startCol + 1) * (endRow - startRow + 1);
                                    var outOfRangeCells =
                                        allCells.Where(x => x.Attribute(NoNamespace.idx) != null &&
                                                       Convert.ToInt32(x.Attribute(NoNamespace.idx)?.Value) >= maxId).ToList();
                                    var nbOutOfRangeCells = outOfRangeCells.Count;
                                    for (int ctCellOut = 0; ctCellOut < nbOutOfRangeCells; ctCellOut += 1)
                                    {
                                        outOfRangeCells[ctCellOut].Remove();
                                    }
                                    // ---------------------

                                    // Update number of elements ptCount
                                    var ptCountCell = oneCache.Descendants(C.ptCount).FirstOrDefault();
                                    if (ptCountCell?.Attribute(NoNamespace.val) != null)
                                    {
                                        ptCountCell.Attribute(NoNamespace.val).Value = allCells.Count().ToString();
                                    }
                                }
                                else
                                {
                                    LogHelper.Instance.LogWarn("Invalid sheet for cached data.");
                                }
                            }
                            else
                            {
                                LogHelper.Instance.LogWarn("No formula defining range of cached data.");
                            }
                        }

                        // Data Label Modification
                        if (content.GraphDataLabelText)
                        {
                            // TODO: Create elements if it does not exist
                            // As of today, the user needs to display Axis value, that will be changed by text by the following code
                            IEnumerable <XElement> dataLabels = oneSerie.Descendants(C.dLbl);
                            var tempLbl = dataLabels.FirstOrDefault();
                            if (tempLbl != null)
                            {
                                XElement parentNode = tempLbl.Parent;

                                // We copied new row if needed
                                int nbDataLabels = dataLabels.Count();
                                if (content.DataLabel.Count() > nbDataLabels)
                                {
                                    var idx         = nbDataLabels - 1;
                                    var lastElement = dataLabels.ElementAt(idx);
                                    while (content.DataLabel.Count() > nbDataLabels)
                                    {
                                        XElement newElement = new XElement(lastElement);
                                        var      idxValue   = newElement.Descendants(C.idx).FirstOrDefault();
                                        // We need to assign IDX at 0 so we're sure it is in the correct range, we change the value afterwards
                                        if (idxValue?.Attribute(NoNamespace.val) != null)
                                        {
                                            idxValue.Attribute(NoNamespace.val).SetValue(0);
                                        }
                                        parentNode?.AddFirst(newElement);
                                        nbDataLabels += 1;
                                    }
                                }
                                // We remove DataLabel is there are too many
                                nbDataLabels = dataLabels.Count();
                                if (content.DataLabel.Count() < nbDataLabels)
                                {
                                    while (content.DataLabel.Count() < nbDataLabels)
                                    {
                                        dataLabels.ElementAt(nbDataLabels - 1).Remove();
                                        nbDataLabels -= 1;
                                    }
                                }
                            }
                            // ----

                            int nbDlbl = dataLabels.Count();
                            for (int ctDlbl = 0; ctDlbl < nbDlbl; ctDlbl += 1)
                            {
                                var oneDataLbl = dataLabels.ElementAt(ctDlbl);
                                var idxTag     = oneDataLbl.Descendants(C.idx).FirstOrDefault();
                                if (idxTag?.Attribute(NoNamespace.val) != null)
                                {
                                    idxTag.Attribute(NoNamespace.val).SetValue(ctDlbl);
                                }

                                var indexVal = oneDataLbl.Descendants(C.idx).FirstOrDefault();
                                if (indexVal?.Attribute(NoNamespace.val) == null || "".Equals(indexVal.Attribute(NoNamespace.val).Value))
                                {
                                    continue;
                                }
                                int idxDataLbl = Convert.ToInt32(indexVal.Attribute(NoNamespace.val).Value);
                                var textTag    = oneDataLbl.Descendants(C.tx).FirstOrDefault();
                                var textValue  = textTag?.Descendants(A.t).FirstOrDefault();
                                textValue?.SetValue(content.DataLabel.ElementAt(idxDataLbl));
                            }
                        }
                        #endregion Serie Treatment
                    }
                }
                else
                {
                    LogHelper.Instance.LogWarn("No cached chart data found.");
                }

                chartPart.PutXDocument(chartDoc);
            }
            catch (Exception exception)
            {
                LogHelper.Instance.LogError("Unexpected exception thrown.", exception);
                throw;
            }
        }
Beispiel #2
0
        private static void ApplyContent(ReportData pClient, OpenXmlPackage pPackage, BlockItem pBlock, TableDefinition pContent, Dictionary <string, string> pOptions)
        {
            try
            {
                string chartId = null;

                var phElem = GetElements(pBlock.OxpBlock, pClient.ReportType)?.ToList();
                if (phElem == null || phElem.Count == 0)
                {
                    LogHelper.Instance.LogError("No placeholder content found.");
                    return;
                }

                #region Get the block Id in document
                var      allElementInPlaceHolder = GetElementsInPlaceHolder(pClient, phElem);
                XElement graphicElement          = phElem.Descendants(A.graphic).FirstOrDefault() ?? phElem.FirstOrDefault(_ => A.graphic.Equals(_.Name));
                if (null != graphicElement)
                {
                    XElement chartElem = graphicElement.Descendants(C.chart).FirstOrDefault();
                    if (null != chartElem)
                    {
                        chartId = chartElem.Attribute(R.id)?.Value;
                    }
                    else
                    {
                        LogHelper.Instance.LogFatal("Graphic object present but not a graph.");
                    }
                }
                else
                {
                    LogHelper.Instance.LogFatal("No graphic / chart object inside the block.");
                }
                if (null == chartId)
                {
                    pBlock.XBlock.ReplaceWith(allElementInPlaceHolder); return;
                }
                #endregion Get the block Id in document

                var chartPart = GetChartPart(pPackage, pBlock, chartId);
                if (null != chartPart)
                {
                    string spreadsheetId = GetSpreadsheetId(chartPart);
                    if (!string.IsNullOrWhiteSpace(spreadsheetId))
                    {
                        #region Associated content management
                        var embedPackage = (EmbeddedPackagePart)chartPart.GetPartById(spreadsheetId);
                        if (null != embedPackage)
                        {
                            using (var ms = new MemoryStream())
                            {
                                #region Set content in memory to work with
                                using (Stream str = embedPackage.GetStream())
                                {
                                    StreamHelper.CopyStream(str, ms);
                                    str.Close();
                                }
                                #endregion Set content in memory to work with

                                using (SpreadsheetDocument spreadsheetDoc = SpreadsheetDocument.Open(ms, true))
                                {
                                    #region Associated Data File content Management
                                    var ws = (OXS.Sheet)spreadsheetDoc.WorkbookPart.Workbook.Sheets.FirstOrDefault();
                                    if (ws != null)
                                    {
                                        string    sheetId = ws.Id;
                                        var       wsp     = (WorksheetPart)spreadsheetDoc.WorkbookPart.GetPartById(sheetId);
                                        XDocument shPart  = wsp.GetXDocument();
                                        XElement  shData  = shPart.Descendants(S.sheetData).FirstOrDefault();

                                        #region Use of the data content (Only data, no titles)
                                        if (null != shData)
                                        {
                                            IEnumerable <XElement> allRows = shData.Descendants(S.row); // => if ToList() cause some graph to fail to generate
                                            int ctRow  = 0;
                                            int nbRows = allRows.Count();

                                            // Cleaning Cells  ======================================================================
                                            // We clean row not having Cell information
                                            int idxRow          = 1;
                                            var nbCorrectSeries = allRows.Where(x => x.Descendants(S.c).Any(y => y.Attribute(NoNamespace.r) != null &&
                                                                                                            y.Attribute(NoNamespace.r)?.Value != ""))
                                                                  .Max(x => x.Descendants(S.c).Count());
                                            for (int ctn = 0; ctn < nbRows; ctn += 1)
                                            {
                                                var oneRow = allRows.ElementAt(ctn);//[ctn];
                                                // DCO - 9/21/2012 - I added the condition that the count of CELL must be indeed equal of numCorrectSeries OR to the number of column
                                                // It happens for graphs with 3 cells defined per row, but only two used (so no Value for third cell), when NbColumns was == 2
                                                var isRowValid = ((oneRow.Descendants(S.c).Count() == nbCorrectSeries || oneRow.Descendants(S.c).Count() >= pContent.NbColumns) &&
                                                                  (oneRow.Descendants(S.c).Descendants(S.v).Count() == oneRow.Descendants(S.c).Count() ||
                                                                   oneRow.Descendants(S.c).Descendants(S.v).Count() >= pContent.NbColumns));

                                                // We remove rows that are not defined in content
                                                if (isRowValid == false || ctRow >= pContent.NbRows)
                                                {
                                                    oneRow.Remove();
                                                    ctn    -= 1;
                                                    nbRows -= 1;
                                                    continue;
                                                }
                                                var _xAttribute = oneRow.Attribute(NoNamespace.r);
                                                if (_xAttribute != null)
                                                {
                                                    _xAttribute.Value = idxRow.ToString();
                                                }
                                                idxRow += 1;
                                            }
                                            // ====================================================================================


                                            // Copying new row  ========================================================================
                                            // We copied new row if needed and extrapolate formula
                                            // Take cell with no t SharedString
                                            nbRows = allRows.Count();
                                            if (pContent.NbRows > nbRows)
                                            {
                                                // We need to detect the best ROW to copy
                                                //    Usually the first row is the header so it contains two cells with SharedString
                                                //    Case 1: For others rows, it will be two cells with value.
                                                //    Case 2: For other rows, it can be one cell with SharedString and one cell with value (in case of App Nane + value)
                                                var oneSerieRow =
                                                    // Case 1
                                                    allRows.FirstOrDefault(x => x.Attribute(NoNamespace.r) != null &&
                                                                           x.Attribute(NoNamespace.r)?.Value != "" && x.Descendants(S.c).Any() &&
                                                                           x.Descendants(S.c).Attributes(NoNamespace.t).Any() == false)
                                                    ?? // Case 2: One or several SharedString, but at least one Value (by using < content.NbColumns)
                                                    allRows.FirstOrDefault(x => x.Attribute(NoNamespace.r) != null &&
                                                                           x.Attribute(NoNamespace.r)?.Value != "" && x.Descendants(S.c).Any() &&
                                                                           x.Descendants(S.c).Attributes(NoNamespace.t).Count() < pContent.NbColumns)
                                                    ?? // Case 3: Any row but the first (avoiding Header)
                                                    allRows.FirstOrDefault(x => x.Attribute(NoNamespace.r) != null &&
                                                                           x.Attribute(NoNamespace.r)?.Value != "" &&
                                                                           x.Attribute(NoNamespace.r)?.Value != "1" && x.Descendants(S.c).Any());

                                                if (oneSerieRow != null)
                                                {
                                                    var previousRowValue = Convert.ToInt32(oneSerieRow.Attribute(NoNamespace.r)?.Value);
                                                    while (nbRows < pContent.NbRows)
                                                    {
                                                        var newRow      = new XElement(oneSerieRow);
                                                        var _xAttribute = newRow.Attribute(NoNamespace.r);
                                                        if (_xAttribute != null)
                                                        {
                                                            _xAttribute.Value = (nbRows + 1).ToString();                      // DCO Correction, ROW ID starts at 1
                                                        }
                                                        var serieCells = newRow.Descendants(S.c);
                                                        foreach (var oneCell in serieCells)
                                                        {
                                                            if (oneCell.Attribute(NoNamespace.r) == null)
                                                            {
                                                                continue;
                                                            }


                                                            var previousFormula = oneCell.Attribute(NoNamespace.r)?.Value;
                                                            // We extrapolate
                                                            int indexRow;
                                                            int indexCol;
                                                            WorksheetAccessorExt.GetRowColumnValue(previousFormula, out indexRow, out indexCol);
                                                            int newRowValue = nbRows + 1 + (indexRow - previousRowValue);
                                                            var _attribute  = oneCell.Attribute(NoNamespace.r);
                                                            if (_attribute != null)
                                                            {
                                                                _attribute.Value = string.Concat(WorksheetAccessor.GetColumnId(indexCol), newRowValue.ToString());
                                                            }

                                                            if (oneCell.Attributes(NoNamespace.t).Any() != true)
                                                            {
                                                                continue;
                                                            }
                                                            var vElement = oneCell.Descendants(S.v).FirstOrDefault();
                                                            if (vElement != null)
                                                            {
                                                                vElement.Value = WorksheetAccessorExt.AddSharedStringValue(spreadsheetDoc, "").ToString();
                                                            }
                                                            // ---
                                                        }
                                                        shData.Add(newRow);
                                                        nbRows += 1;
                                                    }
                                                }
                                                else
                                                {
                                                    LogHelper.Instance.LogWarn("Adding Rows: Could not find a row without a SharedString element.");
                                                }
                                            }
                                            //-----

                                            // Define Sheet Dimension ================================================================
                                            int minStartRow = -1;
                                            int minStartCol = -1;
                                            int maxEndRow   = -1;
                                            int maxEndCol   = -1;
                                            var entireScope = allRows.SelectMany(x => x.Descendants(S.c).Attributes(NoNamespace.r).Select(y => y.Value));
                                            foreach (var oneFormula in entireScope)
                                            {
                                                var startRow = -1;
                                                var endRow   = -1;
                                                var startCol = -1;
                                                var endCol   = -1;
                                                WorksheetAccessorExt.GetFormulaCoord(oneFormula, out startRow, out startCol,
                                                                                     out endRow, out endCol);
                                                if (minStartRow == -1 || startRow < minStartRow)
                                                {
                                                    minStartRow = startRow;
                                                }
                                                if (minStartCol == -1 || startCol < minStartCol)
                                                {
                                                    minStartCol = startCol;
                                                }
                                                if (maxEndRow == -1 || endRow > maxEndRow)
                                                {
                                                    maxEndRow = endRow;
                                                }
                                                if (maxEndCol == -1 || endCol > maxEndCol)
                                                {
                                                    maxEndCol = endCol;
                                                }
                                            }
                                            XElement sheetDimension = shPart.Descendants(S.s + "dimension").FirstOrDefault();
                                            if (sheetDimension?.Attribute(NoNamespace._ref) != null)
                                            {
                                                sheetDimension.Attribute(NoNamespace._ref)?.SetValue(WorksheetAccessorExt.SetFormula("", minStartRow, minStartCol, maxEndRow, maxEndCol, false));
                                            }
                                            // ====================================================================================

                                            int contentEltCount = pContent.Data?.Count() ?? 0;
                                            // Apply values =======================================================================
                                            for (int ctn = 0; ctn < nbRows; ctn++)
                                            {
                                                var oneRow = allRows.ElementAt(ctn);
                                                // TODO: We may have to correct the "spans" in:  <row r="1" spans="1:3"
                                                List <XElement> allCells = oneRow.Descendants(S.c).ToList();
                                                var             ctCell   = 0;
                                                int             nbCells  = allCells.Count;
                                                for (int ctc = 0; ctc < nbCells; ctc++)
                                                {
                                                    var oneCell = allCells[ctc];

                                                    // We remove cell if they are not defined as content columns
                                                    if (ctCell >= pContent.NbColumns)
                                                    {
                                                        LogHelper.Instance.LogWarn("More cells that defined content ");
                                                        if (null != oneCell.Parent)
                                                        {
                                                            oneCell.Remove();
                                                        }

                                                        ctc     -= 1;
                                                        nbCells -= 1;
                                                        continue;
                                                    }

                                                    // We inject text
                                                    var targetText = ((ctRow * pContent.NbColumns + ctCell) < contentEltCount ?
                                                                      pContent.Data?.ElementAt(ctRow * pContent.NbColumns + ctCell) :
                                                                      string.Empty);
                                                    if (null != targetText && !"<KEEP>".Equals(targetText)) // Keep for managing UniversalGraph
                                                    {
                                                        var isSharedString = oneCell.Attribute(NoNamespace.t);
                                                        if (null != isSharedString && "s".Equals(isSharedString.Value))
                                                        {
                                                            if ("".Equals(targetText))
                                                            {
                                                                LogHelper.Instance.LogWarn("Target Text empty for Shared String, this can create abnormal behavior.");
                                                            }
                                                            var idx = Convert.ToInt32(oneCell.Value);
                                                            WorksheetAccessorExt.SetSharedStringValue(spreadsheetDoc, idx, targetText);
                                                        }
                                                        else
                                                        {
                                                            XElement cell = oneCell.Descendants(S.v).FirstOrDefault();
                                                            if (null != cell)
                                                            {
                                                                cell.Value = targetText;
                                                            }
                                                            else
                                                            {
                                                                LogHelper.Instance.LogWarn("No correct cell value found");
                                                            }
                                                        }
                                                    }
                                                    ctCell += 1;
                                                }
                                                ctRow += 1;
                                            }
                                        }
                                        else
                                        {
                                            LogHelper.Instance.LogWarn("Embedded spreadsheet is not formatted correctly");
                                        }
                                        // ====================================================================================
                                        #endregion Get and use of the data content (Only data, no titles)

                                        // We modify Table Definition (defining scope of Graph)
                                        foreach (TableDefinitionPart t in wsp.TableDefinitionParts)
                                        {
                                            t.Table.Reference = String.Concat(WorksheetAccessor.GetColumnId(1), 1, ":",
                                                                              WorksheetAccessor.GetColumnId(pContent.NbColumns), pContent.NbRows);

                                            // We reduce the scope TableColumn if needed
                                            var columnCount = t.Table.TableColumns.Count;
                                            for (int ctCol = 0; ctCol < columnCount; ctCol += 1)
                                            {
                                                var tabColumn = t.Table.TableColumns.ElementAt(ctCol);
                                                if (ctCol >= pContent.NbColumns)
                                                {
                                                    tabColumn.Remove();
                                                    ctCol       -= 1;
                                                    columnCount -= 1; // DCO - 10/23/2012 - Correction when reducing scope to a column (count is corrected afterwards).
                                                    continue;
                                                }

                                                // We align column name with the correct Shared String
                                                if (!string.IsNullOrEmpty(pContent.Data?.ElementAt(ctCol)) && ctCol < pContent.NbColumns && "<KEEP>" != pContent.Data.ElementAt(ctCol))
                                                {
                                                    tabColumn.SetAttribute(new OpenXmlAttribute("", "name", "", pContent.Data.ElementAt(ctCol)));
                                                }
                                            }

                                            // The Count attribute is not updated correctly, so we do the work for them :)
                                            if (pContent.NbColumns < t.Table.TableColumns.Count)
                                            {
                                                t.Table.TableColumns.SetAttribute(new OpenXmlAttribute("", "count", "", pContent.NbColumns.ToString()));
                                            }
                                        }
                                        // We save the XML content
                                        wsp.PutXDocument(shPart);
                                    }
                                    // We update cached data in Word document
                                    UpdateCachedValues(pClient, chartPart, spreadsheetDoc, pContent);
                                    #endregion Associated Data File content Management
                                }
                                // Write the modified memory stream back
                                // into the embedded package part.
                                using (Stream s = embedPackage.GetStream())
                                {
                                    ms.WriteTo(s);
                                    s.SetLength(ms.Length);
                                }
                            }
                        }
                        else
                        {
                            LogHelper.Instance.LogWarn("No embedded excel file found.");
                        }
                        #endregion Associated content management
                    }
                    else
                    {
                        LogHelper.Instance.LogWarn("No spreadsheet identifier found.");
                    }

                    #region Additionnal parameters

                    if (null == pContent.GraphOptions || !pContent.GraphOptions.HasConfiguration)
                    {
                        return;
                    }
                    Chart    chart = chartPart.ChartSpace.Descendants <Chart>().FirstOrDefault();
                    PlotArea p_c   = chart?.PlotArea;
                    var      primaryVerticalAxis = p_c?.Descendants <ValueAxis>().FirstOrDefault(_ => "valAx".Equals(_.LocalName));
                    if (pContent.GraphOptions.AxisConfiguration.VerticalAxisMinimal.HasValue)
                    {
                        if (primaryVerticalAxis != null)
                        {
                            primaryVerticalAxis.Scaling.MinAxisValue.Val = DoubleValue.FromDouble(pContent.GraphOptions.AxisConfiguration.VerticalAxisMinimal.Value);
                        }
                    }
                    if (!pContent.GraphOptions.AxisConfiguration.VerticalAxisMaximal.HasValue)
                    {
                        return;
                    }
                    // ReSharper disable once PossibleInvalidOperationException
                    if (primaryVerticalAxis != null)
                    {
                        primaryVerticalAxis.Scaling.MaxAxisValue.Val = DoubleValue.FromDouble(pContent.GraphOptions.AxisConfiguration.VerticalAxisMaximal.Value);
                    }

                    #endregion Additionnal parameters
                }
            }
            catch (Exception exception)
            {
                LogHelper.Instance.LogError("Unexpected exception thrown.", exception);
                throw;
            }
        }