private static bool MatchFont(XDocument sXDoc, XElement xf, CellDfn cell)
        {
            if (((int?)xf.Attribute(SSNoNamespace.applyFont) == 0 ||
                 xf.Attribute(SSNoNamespace.applyFont) == null) &&
                (cell.Bold == null || cell.Bold == false) &&
                (cell.Italic == null || cell.Italic == false))
            {
                return(true);
            }

            if (((int?)xf.Attribute(SSNoNamespace.applyFont) == 0 ||
                 xf.Attribute(SSNoNamespace.applyFont) == null) &&
                (cell.Bold == true ||
                 cell.Italic == true))
            {
                return(false);
            }

            var fontId = (int)xf.Attribute(SSNoNamespace.fontId);
            var font   = sXDoc
                         .Root
                         .Element(S.fonts)
                         .Elements(S.font)
                         .ElementAt(fontId);
            var fabFont = new XElement(S.font,
                                       cell.Bold == true ? new XElement(S.b) : null,
                                       cell.Italic == true ? new XElement(S.i) : null);
            var match = XNode.DeepEquals(font, fabFont);

            return(match);
        }
        private static bool CompareStyles(XDocument sXDoc, XElement xf, CellDfn cell)
        {
            var matchFont      = MatchFont(sXDoc, xf, cell);
            var matchAlignment = MatchAlignment(xf, cell);
            var matchFormat    = MatchFormat(sXDoc, xf, cell);

            return(matchFont && matchAlignment && matchFormat);
        }
        private static bool MatchFormat(XDocument sXDoc, XElement xf, CellDfn cell)
        {
            if ((int?)xf.Attribute(SSNoNamespace.applyNumberFormat) != 1 &&
                cell.FormatCode == null)
            {
                return(true);
            }

            if (xf.Attribute(SSNoNamespace.applyNumberFormat) == null &&
                cell.FormatCode != null)
            {
                return(false);
            }

            var numFmtId = (int)xf.Attribute(SSNoNamespace.numFmtId);
            int?nfi      = null;

            if (cell.FormatCode != null)
            {
                if (CellDfn.StandardFormats.ContainsKey(cell.FormatCode))
                {
                    nfi = CellDfn.StandardFormats[cell.FormatCode];
                }

                if (nfi == numFmtId)
                {
                    return(true);
                }
            }
            var numFmts = sXDoc
                          .Root
                          .Element(S.numFmts);

            if (numFmts == null)
            {
                return(false);
            }

            var numFmt = numFmts
                         .Elements(S.numFmt)
                         .FirstOrDefault(numFmtElement =>
                                         (int)numFmtElement.Attribute(SSNoNamespace.numFmtId) == numFmtId);

            if (numFmt == null)
            {
                return(false);
            }

            var styleFormatCode = (string)numFmt.Attribute(SSNoNamespace.formatCode);
            var match           = styleFormatCode == cell.FormatCode;

            return(match);
        }
        private static bool MatchAlignment(XElement xf, CellDfn cell)
        {
            if ((int?)xf.Attribute(SSNoNamespace.applyAlignment) == 0 ||
                xf.Attribute(SSNoNamespace.applyAlignment) == null &&
                cell.HorizontalCellAlignment == null)
            {
                return(true);
            }

            if (xf.Attribute(SSNoNamespace.applyAlignment) == null &&
                cell.HorizontalCellAlignment != null)
            {
                return(false);
            }

            var alignment = (string)xf.Element(S.alignment).Attribute(SSNoNamespace.horizontal);
            var match     = alignment == cell.HorizontalCellAlignment.ToString().ToLower();

            return(match);
        }
        private static int GetFontId(XDocument sXDoc, CellDfn cell)
        {
            var fonts = sXDoc.Root.Element(S.fonts);

            if (fonts == null)
            {
                fonts = new XElement(S.fonts,
                                     new XAttribute(SSNoNamespace.count, 1),
                                     new XElement(S.font,
                                                  cell.Bold == true ? new XElement(S.b) : null,
                                                  cell.Italic == true ? new XElement(S.i) : null));
                sXDoc.Root.Add(fonts);
                return(0);
            }
            var font = new XElement(S.font,
                                    cell.Bold == true ? new XElement(S.b) : null,
                                    cell.Italic == true ? new XElement(S.i) : null);

            fonts.Add(font);
            var count = (int)fonts.Attribute(SSNoNamespace.count);

            fonts.SetAttributeValue(SSNoNamespace.count, count + 1);
            return(count);
        }
        private static int GetCellStyle(SpreadsheetDocument sDoc, CellDfn cell)
        {
            var sXDoc = sDoc.WorkbookPart.WorkbookStylesPart.GetXDocument();
            var match = sXDoc
                        .Root
                        .Element(S.cellXfs)
                        .Elements(S.xf)
                        .Select((e, i) => new
            {
                Element = e,
                Index   = i,
            })
                        .FirstOrDefault(xf => CompareStyles(sXDoc, xf.Element, cell));

            if (match != null)
            {
                return(match.Index);
            }

            // if no match, then create a style
            var newId = CreateNewStyle(sXDoc, cell);

            return(newId);
        }
        private static int CreateNewStyle(XDocument sXDoc, CellDfn cell)
        {
            XAttribute?applyFont = null;
            XAttribute?fontId    = null;

            if (cell.Bold == true || cell.Italic == true)
            {
                applyFont = new XAttribute(SSNoNamespace.applyFont, 1);
                fontId    = new XAttribute(SSNoNamespace.fontId, GetFontId(sXDoc, cell));
            }
            XAttribute?applyAlignment = null;
            XElement?  alignment      = null;

            if (cell.HorizontalCellAlignment != null)
            {
                applyAlignment = new XAttribute(SSNoNamespace.applyAlignment, 1);
                alignment      = new XElement(S.alignment,
                                              new XAttribute(SSNoNamespace.horizontal, cell.HorizontalCellAlignment.ToString().ToLower()));
            }
            XAttribute?applyNumberFormat = null;
            XAttribute?numFmtId          = null;

            if (cell.FormatCode != null)
            {
                if (CellDfn.StandardFormats.ContainsKey(cell.FormatCode))
                {
                    applyNumberFormat = new XAttribute(SSNoNamespace.applyNumberFormat, 1);
                    numFmtId          = new XAttribute(SSNoNamespace.numFmtId, CellDfn.StandardFormats[cell.FormatCode]);
                }
                else
                {
                    applyNumberFormat = new XAttribute(SSNoNamespace.applyNumberFormat, 1);
                    numFmtId          = new XAttribute(SSNoNamespace.numFmtId, GetNumFmtId(sXDoc, cell.FormatCode));
                }
            }
            var newXf = new XElement(S.xf,
                                     applyFont,
                                     fontId,
                                     applyAlignment,
                                     alignment,
                                     applyNumberFormat,
                                     numFmtId);
            var cellXfs = sXDoc
                          .Root
                          .Element(S.cellXfs);

            if (cellXfs == null)
            {
                cellXfs = new XElement(S.cellXfs,
                                       new XAttribute(SSNoNamespace.count, 1),
                                       newXf);
                return(0);
            }
            else
            {
                var currentCount = (int)cellXfs.Attribute(SSNoNamespace.count);
                cellXfs.SetAttributeValue(SSNoNamespace.count, currentCount + 1);
                cellXfs.Add(newXf);
                return(currentCount);
            }
        }