| /******************************************************************************* |
| * You may amend and distribute as you like, but don't remove this header! |
| * |
| * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. |
| * See http://www.codeplex.com/EPPlus for details. |
| * |
| * Copyright (C) 2011 Jan K�llman |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * See the GNU Lesser General Public License for more details. |
| * |
| * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php |
| * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html |
| * |
| * All code and executables are provided "as is" with no warranty either express or implied. |
| * The author accepts no liability for any damage or loss of business that this product may cause. |
| * |
| * Code change notes: |
| * |
| * Author Change Date |
| * ****************************************************************************** |
| * Jan K�llman Initial Release 2009-10-01 |
| * Jan K�llman License changed GPL-->LGPL 2011-12-27 |
| *******************************************************************************/ |
| |
| using System; |
| using System.Linq; |
| using System.Xml; |
| using OfficeOpenXml.ConditionalFormatting; |
| using OfficeOpenXml.Style; |
| using OfficeOpenXml.Style.Dxf; |
| using OfficeOpenXml.Style.XmlAccess; |
| |
| namespace OfficeOpenXml; |
| |
| /// <summary> |
| /// Containts all shared cell styles for a workbook |
| /// </summary> |
| public sealed class ExcelStyles : XmlHelper { |
| private const string _numberFormatsPath = "d:styleSheet/d:numFmts"; |
| private const string _fontsPath = "d:styleSheet/d:fonts"; |
| private const string _fillsPath = "d:styleSheet/d:fills"; |
| private const string _bordersPath = "d:styleSheet/d:borders"; |
| private const string _cellStyleXfsPath = "d:styleSheet/d:cellStyleXfs"; |
| private const string _cellXfsPath = "d:styleSheet/d:cellXfs"; |
| private const string _cellStylesPath = "d:styleSheet/d:cellStyles"; |
| private const string _dxfsPath = "d:styleSheet/d:dxfs"; |
| |
| //internal Dictionary<int, ExcelXfs> Styles = new Dictionary<int, ExcelXfs>(); |
| private readonly XmlDocument _styleXml; |
| private readonly ExcelWorkbook _wb; |
| private readonly XmlNamespaceManager _nameSpaceManager; |
| internal int _nextDfxNumFmtID = 164; |
| |
| internal ExcelStyles(XmlNamespaceManager nameSpaceManager, XmlDocument xml, ExcelWorkbook wb) |
| : base(nameSpaceManager, xml) { |
| _styleXml = xml; |
| _wb = wb; |
| _nameSpaceManager = nameSpaceManager; |
| SchemaNodeOrder = new[] { |
| "numFmts", |
| "fonts", |
| "fills", |
| "borders", |
| "cellStyleXfs", |
| "cellXfs", |
| "cellStyles", |
| "dxfs", |
| }; |
| LoadFromDocument(); |
| } |
| |
| /// <summary> |
| /// Loads the style XML to memory |
| /// </summary> |
| private void LoadFromDocument() { |
| //NumberFormats |
| ExcelNumberFormatXml.AddBuildIn(NameSpaceManager, NumberFormats); |
| XmlNode numNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager); |
| if (numNode != null) { |
| foreach (XmlNode n in numNode) { |
| ExcelNumberFormatXml nf = new ExcelNumberFormatXml(_nameSpaceManager, n); |
| NumberFormats.Add(nf.Id, nf); |
| if (nf.NumFmtId >= NumberFormats.NextId) { |
| NumberFormats.NextId = nf.NumFmtId + 1; |
| } |
| } |
| } |
| |
| //Fonts |
| XmlNode fontNode = _styleXml.SelectSingleNode(_fontsPath, _nameSpaceManager); |
| foreach (XmlNode n in fontNode) { |
| ExcelFontXml f = new ExcelFontXml(_nameSpaceManager, n); |
| Fonts.Add(f.Id, f); |
| } |
| |
| //Fills |
| XmlNode fillNode = _styleXml.SelectSingleNode(_fillsPath, _nameSpaceManager); |
| foreach (XmlNode n in fillNode) { |
| ExcelFillXml f; |
| if (n.FirstChild != null && n.FirstChild.LocalName == "gradientFill") { |
| f = new ExcelGradientFillXml(_nameSpaceManager, n); |
| } else { |
| f = new(_nameSpaceManager, n); |
| } |
| Fills.Add(f.Id, f); |
| } |
| |
| //Borders |
| XmlNode borderNode = _styleXml.SelectSingleNode(_bordersPath, _nameSpaceManager); |
| foreach (XmlNode n in borderNode) { |
| ExcelBorderXml b = new ExcelBorderXml(_nameSpaceManager, n); |
| Borders.Add(b.Id, b); |
| } |
| |
| //cellStyleXfs |
| XmlNode styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager); |
| if (styleXfsNode != null) { |
| foreach (XmlNode n in styleXfsNode) { |
| ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this); |
| CellStyleXfs.Add(item.Id, item); |
| } |
| } |
| |
| XmlNode styleNode = _styleXml.SelectSingleNode(_cellXfsPath, _nameSpaceManager); |
| for (int i = 0; i < styleNode.ChildNodes.Count; i++) { |
| XmlNode n = styleNode.ChildNodes[i]; |
| ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this); |
| CellXfs.Add(item.Id, item); |
| } |
| |
| //cellStyle |
| XmlNode namedStyleNode = _styleXml.SelectSingleNode(_cellStylesPath, _nameSpaceManager); |
| if (namedStyleNode != null) { |
| foreach (XmlNode n in namedStyleNode) { |
| ExcelNamedStyleXml item = new ExcelNamedStyleXml(_nameSpaceManager, n, this); |
| NamedStyles.Add(item.Name, item); |
| } |
| } |
| |
| //dxfsPath |
| XmlNode dxfsNode = _styleXml.SelectSingleNode(_dxfsPath, _nameSpaceManager); |
| if (dxfsNode != null) { |
| foreach (XmlNode x in dxfsNode) { |
| ExcelDxfStyleConditionalFormatting item = new ExcelDxfStyleConditionalFormatting( |
| _nameSpaceManager, |
| x, |
| this); |
| Dxfs.Add(item.Id, item); |
| } |
| } |
| } |
| |
| internal ExcelStyle GetStyleObject(int id, int positionId, string address) { |
| if (id < 0) { |
| id = 0; |
| } |
| return new(this, positionId, address, id); |
| } |
| |
| internal int GetStyleId(ExcelWorksheet ws, int row, int col) { |
| int v = 0; |
| if (ws._styles.Exists(row, col, ref v)) { |
| return v; |
| } |
| if (ws._styles.Exists( |
| row, |
| 0, |
| ref v)) //First Row |
| { |
| return v; |
| } // then column |
| if (ws._styles.Exists(0, col, ref v)) { |
| return v; |
| } |
| int r = 0, |
| c = col; |
| if (ws._values.PrevCell(ref r, ref c)) { |
| var column = ws._values.GetValue(0, c) as ExcelColumn; |
| if (column != null |
| && column.ColumnMax |
| >= col) //Fixes issue 15174 |
| { |
| return ws._styles.GetValue(0, c); |
| } |
| return 0; |
| } |
| return 0; |
| } |
| |
| public ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats = new(); |
| public ExcelStyleCollection<ExcelFontXml> Fonts = new(); |
| public ExcelStyleCollection<ExcelFillXml> Fills = new(); |
| public ExcelStyleCollection<ExcelBorderXml> Borders = new(); |
| public ExcelStyleCollection<ExcelXfs> CellStyleXfs = new(); |
| public ExcelStyleCollection<ExcelXfs> CellXfs = new(); |
| public ExcelStyleCollection<ExcelNamedStyleXml> NamedStyles = new(); |
| public ExcelStyleCollection<ExcelDxfStyleConditionalFormatting> Dxfs = new(); |
| |
| internal string Id => ""; |
| |
| public ExcelNamedStyleXml CreateNamedStyle(string name) { |
| return CreateNamedStyle(name, null); |
| } |
| |
| public ExcelNamedStyleXml CreateNamedStyle(string name, ExcelStyle template) { |
| if (_wb.Styles.NamedStyles.ExistsKey(name)) { |
| throw new(string.Format("Key {0} already exists in collection", name)); |
| } |
| |
| ExcelNamedStyleXml style; |
| style = new(NameSpaceManager, this); |
| int xfIdCopy, |
| positionId; |
| ExcelStyles styles; |
| if (template == null) { |
| // style.Style = new ExcelStyle(this, NamedStylePropertyChange, -1, name, 0); |
| xfIdCopy = 0; |
| positionId = -1; |
| styles = this; |
| } else { |
| if (template.PositionID < 0 && template.Styles == this) { |
| xfIdCopy = template.Index; |
| positionId = template.PositionID; |
| styles = this; |
| //style.Style = new ExcelStyle(this, NamedStylePropertyChange, Template.PositionID, name, Template.Index); |
| //style.StyleXfId = Template.Index; |
| } else { |
| xfIdCopy = template.XfId; |
| positionId = -1; |
| styles = template.Styles; |
| } |
| } |
| //Clone namedstyle |
| int styleXfId = CloneStyle(styles, xfIdCopy, true); |
| //Close cells style |
| CellStyleXfs[styleXfId].XfId = CellStyleXfs.Count - 1; |
| int xfid = CloneStyle(styles, xfIdCopy, false, true); //Always add a new style (We create a new named style here) |
| CellXfs[xfid].XfId = styleXfId; |
| style.Style = new(this, positionId, name, styleXfId); |
| style.StyleXfId = styleXfId; |
| |
| style.Name = name; |
| int ix = _wb.Styles.NamedStyles.Add(style.Name, style); |
| style.Style.SetIndex(ix); |
| //style.Style.XfId = ix; |
| return style; |
| } |
| |
| public void UpdateXml() { |
| RemoveUnusedStyles(); |
| |
| //NumberFormat |
| XmlNode nfNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager); |
| if (nfNode == null) { |
| CreateNode(_numberFormatsPath, true); |
| nfNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager); |
| } else { |
| nfNode.RemoveAll(); |
| } |
| |
| int count = 0; |
| int normalIx = NamedStyles.FindIndexById("Normal"); |
| if (NamedStyles.Count > 0 |
| && normalIx >= 0 |
| && NamedStyles[normalIx].Style.Numberformat.NumFmtID >= 164) { |
| ExcelNumberFormatXml nf = NumberFormats[NumberFormats.FindIndexById( |
| NamedStyles[normalIx].Style.Numberformat.Id)]; |
| nfNode.AppendChild( |
| nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage._schemaMain))); |
| nf.newID = count++; |
| } |
| foreach (ExcelNumberFormatXml nf in NumberFormats) { |
| if (!nf.BuildIn /*&& nf.newID<0*/) //Buildin formats are not updated. |
| { |
| nfNode.AppendChild( |
| nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage._schemaMain))); |
| nf.newID = count; |
| count++; |
| } |
| } |
| (nfNode as XmlElement).SetAttribute("count", count.ToString()); |
| |
| //Font |
| count = 0; |
| XmlNode fntNode = _styleXml.SelectSingleNode(_fontsPath, _nameSpaceManager); |
| fntNode.RemoveAll(); |
| |
| //Normal should be first in the collection |
| if (NamedStyles.Count > 0 && normalIx >= 0 && NamedStyles[normalIx].Style.Font.Index > 0) { |
| ExcelFontXml fnt = Fonts[NamedStyles[normalIx].Style.Font.Index]; |
| fntNode.AppendChild( |
| fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage._schemaMain))); |
| fnt.newID = count++; |
| } |
| |
| foreach (ExcelFontXml fnt in Fonts) { |
| if (fnt.useCnt |
| > 0 /* && fnt.newID<0*/) { |
| fntNode.AppendChild( |
| fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage._schemaMain))); |
| fnt.newID = count; |
| count++; |
| } |
| } |
| (fntNode as XmlElement).SetAttribute("count", count.ToString()); |
| |
| //Fills |
| count = 0; |
| XmlNode fillsNode = _styleXml.SelectSingleNode(_fillsPath, _nameSpaceManager); |
| fillsNode.RemoveAll(); |
| Fills[0].useCnt = 1; //Must exist (none); |
| Fills[1].useCnt = 1; //Must exist (gray125); |
| foreach (ExcelFillXml fill in Fills) { |
| if (fill.useCnt > 0) { |
| fillsNode.AppendChild( |
| fill.CreateXmlNode(_styleXml.CreateElement("fill", ExcelPackage._schemaMain))); |
| fill.newID = count; |
| count++; |
| } |
| } |
| |
| (fillsNode as XmlElement).SetAttribute("count", count.ToString()); |
| |
| //Borders |
| count = 0; |
| XmlNode bordersNode = _styleXml.SelectSingleNode(_bordersPath, _nameSpaceManager); |
| bordersNode.RemoveAll(); |
| Borders[0].useCnt = 1; //Must exist blank; |
| foreach (ExcelBorderXml border in Borders) { |
| if (border.useCnt > 0) { |
| bordersNode.AppendChild( |
| border.CreateXmlNode(_styleXml.CreateElement("border", ExcelPackage._schemaMain))); |
| border.newID = count; |
| count++; |
| } |
| } |
| (bordersNode as XmlElement).SetAttribute("count", count.ToString()); |
| |
| XmlNode styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager); |
| if (styleXfsNode == null && NamedStyles.Count > 0) { |
| CreateNode(_cellStyleXfsPath); |
| styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager); |
| } |
| if (NamedStyles.Count > 0) { |
| styleXfsNode.RemoveAll(); |
| } |
| //NamedStyles |
| count = normalIx > -1 ? 1 : 0; //If we have a normal style, we make sure it's added first. |
| |
| XmlNode cellStyleNode = _styleXml.SelectSingleNode(_cellStylesPath, _nameSpaceManager); |
| if (cellStyleNode != null) { |
| cellStyleNode.RemoveAll(); |
| } |
| XmlNode cellXfsNode = _styleXml.SelectSingleNode(_cellXfsPath, _nameSpaceManager); |
| cellXfsNode.RemoveAll(); |
| |
| if (NamedStyles.Count > 0 && normalIx >= 0) { |
| NamedStyles[normalIx].newID = 0; |
| AddNamedStyle(0, styleXfsNode, cellXfsNode, NamedStyles[normalIx]); |
| } |
| foreach (ExcelNamedStyleXml style in NamedStyles) { |
| if (!style.Name.Equals("normal", StringComparison.InvariantCultureIgnoreCase)) { |
| AddNamedStyle(count++, styleXfsNode, cellXfsNode, style); |
| } else { |
| style.newID = 0; |
| } |
| cellStyleNode.AppendChild( |
| style.CreateXmlNode(_styleXml.CreateElement("cellStyle", ExcelPackage._schemaMain))); |
| } |
| if (cellStyleNode != null) { |
| (cellStyleNode as XmlElement).SetAttribute("count", count.ToString()); |
| } |
| if (styleXfsNode != null) { |
| (styleXfsNode as XmlElement).SetAttribute("count", count.ToString()); |
| } |
| |
| //CellStyle |
| int xfix = 0; |
| foreach (ExcelXfs xf in CellXfs) { |
| if (xf.useCnt > 0 && !(normalIx >= 0 && NamedStyles[normalIx].XfId == xfix)) { |
| cellXfsNode.AppendChild( |
| xf.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain))); |
| xf.newID = count; |
| count++; |
| } |
| xfix++; |
| } |
| (cellXfsNode as XmlElement).SetAttribute("count", count.ToString()); |
| |
| //Set dxf styling for conditional Formatting |
| XmlNode dxfsNode = _styleXml.SelectSingleNode(_dxfsPath, _nameSpaceManager); |
| foreach (var ws in _wb.Worksheets) { |
| if (ws is ExcelChartsheet) { |
| continue; |
| } |
| foreach (var cf in ws.ConditionalFormatting) { |
| if (cf.Style.HasValue) { |
| int ix = Dxfs.FindIndexById(cf.Style.Id); |
| if (ix < 0) { |
| ((ExcelConditionalFormattingRule)cf).DxfId = Dxfs.Count; |
| Dxfs.Add(cf.Style.Id, cf.Style); |
| var elem = ((XmlDocument)TopNode).CreateElement("d", "dxf", ExcelPackage._schemaMain); |
| cf.Style.CreateNodes(new XmlHelperInstance(NameSpaceManager, elem), ""); |
| dxfsNode.AppendChild(elem); |
| } else { |
| ((ExcelConditionalFormattingRule)cf).DxfId = ix; |
| } |
| } |
| } |
| } |
| if (dxfsNode != null) { |
| (dxfsNode as XmlElement).SetAttribute("count", Dxfs.Count.ToString()); |
| } |
| } |
| |
| private void AddNamedStyle( |
| int id, |
| XmlNode styleXfsNode, |
| XmlNode cellXfsNode, |
| ExcelNamedStyleXml style) { |
| var styleXfs = CellStyleXfs[style.StyleXfId]; |
| styleXfsNode.AppendChild( |
| styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain), true)); |
| styleXfs.newID = id; |
| styleXfs.XfId = style.StyleXfId; |
| |
| var ix = CellXfs.FindIndexById(styleXfs.Id); |
| if (ix < 0) { |
| cellXfsNode.AppendChild( |
| styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain))); |
| } else { |
| if (id < 0) { |
| CellXfs[ix].XfId = id; |
| } |
| cellXfsNode.AppendChild( |
| CellXfs[ix].CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain))); |
| CellXfs[ix].useCnt = 0; |
| CellXfs[ix].newID = id; |
| } |
| |
| if (style.XfId >= 0) { |
| style.XfId = CellXfs[style.XfId].newID; |
| } else { |
| style.XfId = 0; |
| } |
| } |
| |
| private void RemoveUnusedStyles() { |
| CellXfs[0].useCnt = 1; //First item is allways used. |
| foreach (ExcelWorksheet sheet in _wb.Worksheets) { |
| var cse = new CellsStoreEnumerator<int>(sheet._styles); |
| while (cse.Next()) { |
| var v = cse.Value; |
| if (v >= 0) { |
| CellXfs[v].useCnt++; |
| } |
| } |
| } |
| foreach (ExcelNamedStyleXml ns in NamedStyles) { |
| CellStyleXfs[ns.StyleXfId].useCnt++; |
| } |
| |
| foreach (ExcelXfs xf in CellXfs) { |
| if (xf.useCnt > 0) { |
| if (xf.FontId >= 0) { |
| Fonts[xf.FontId].useCnt++; |
| } |
| if (xf.FillId >= 0) { |
| Fills[xf.FillId].useCnt++; |
| } |
| if (xf.BorderId >= 0) { |
| Borders[xf.BorderId].useCnt++; |
| } |
| } |
| } |
| foreach (ExcelXfs xf in CellStyleXfs) { |
| if (xf.useCnt > 0) { |
| if (xf.FontId >= 0) { |
| Fonts[xf.FontId].useCnt++; |
| } |
| if (xf.FillId >= 0) { |
| Fills[xf.FillId].useCnt++; |
| } |
| if (xf.BorderId >= 0) { |
| Borders[xf.BorderId].useCnt++; |
| } |
| } |
| } |
| } |
| |
| internal int GetStyleIdFromName(string name) { |
| int i = NamedStyles.FindIndexById(name); |
| if (i >= 0) { |
| int id = NamedStyles[i].XfId; |
| if (id < 0) { |
| int styleXfId = NamedStyles[i].StyleXfId; |
| ExcelXfs newStyle = CellStyleXfs[styleXfId].Copy(); |
| newStyle.XfId = styleXfId; |
| id = CellXfs.FindIndexById(newStyle.Id); |
| if (id < 0) { |
| id = CellXfs.Add(newStyle.Id, newStyle); |
| } |
| NamedStyles[i].XfId = id; |
| } |
| return id; |
| } |
| return 0; |
| //throw(new Exception("Named style does not exist")); |
| } |
| |
| private string GetXmlNode(XmlNode node) { |
| if (node == null) { |
| return ""; |
| } |
| if (node.Value != null) { |
| return node.Value; |
| } |
| return ""; |
| } |
| |
| internal int CloneStyle(ExcelStyles style, int styleId) { |
| return CloneStyle(style, styleId, false, false); |
| } |
| |
| internal int CloneStyle(ExcelStyles style, int styleId, bool isNamedStyle) { |
| return CloneStyle(style, styleId, isNamedStyle, false); |
| } |
| |
| internal int CloneStyle(ExcelStyles style, int styleId, bool isNamedStyle, bool allwaysAdd) { |
| ExcelXfs xfs; |
| lock (style) { |
| if (isNamedStyle) { |
| xfs = style.CellStyleXfs[styleId]; |
| } else { |
| xfs = style.CellXfs[styleId]; |
| } |
| ExcelXfs newXfs = xfs.Copy(this); |
| //Numberformat |
| if (xfs.NumberFormatId > 0) { |
| //rake36: Two problems here... |
| //rake36: 1. the first time through when format stays equal to String.Empty, it adds a string.empty to the list of Number Formats |
| //rake36: 2. when adding a second sheet, if the numberformatid == 164, it finds the 164 added by previous sheets but was using the array index |
| //rake36: for the numberformatid |
| |
| string format = string.Empty; |
| foreach (var fmt in style.NumberFormats) { |
| if (fmt.NumFmtId == xfs.NumberFormatId) { |
| format = fmt.Format; |
| break; |
| } |
| } |
| //rake36: Don't add another format if it's blank |
| if (!String.IsNullOrEmpty(format)) { |
| int ix = NumberFormats.FindIndexById(format); |
| if (ix < 0) { |
| var item = new ExcelNumberFormatXml(NameSpaceManager) { |
| Format = format, |
| NumFmtId = NumberFormats.NextId++, |
| }; |
| NumberFormats.Add(format, item); |
| //rake36: Use the just added format id |
| newXfs.NumberFormatId = item.NumFmtId; |
| } else { |
| //rake36: Use the format id defined by the index... not the index itself |
| newXfs.NumberFormatId = NumberFormats[ix].NumFmtId; |
| } |
| } |
| } |
| |
| //Font |
| if (xfs.FontId > -1) { |
| int ix = Fonts.FindIndexById(xfs.Font.Id); |
| if (ix < 0) { |
| ExcelFontXml item = style.Fonts[xfs.FontId].Copy(); |
| ix = Fonts.Add(xfs.Font.Id, item); |
| } |
| newXfs.FontId = ix; |
| } |
| |
| //Border |
| if (xfs.BorderId > -1) { |
| int ix = Borders.FindIndexById(xfs.Border.Id); |
| if (ix < 0) { |
| ExcelBorderXml item = style.Borders[xfs.BorderId].Copy(); |
| ix = Borders.Add(xfs.Border.Id, item); |
| } |
| newXfs.BorderId = ix; |
| } |
| |
| //Fill |
| if (xfs.FillId > -1) { |
| int ix = Fills.FindIndexById(xfs.Fill.Id); |
| if (ix < 0) { |
| var item = style.Fills[xfs.FillId].Copy(); |
| ix = Fills.Add(xfs.Fill.Id, item); |
| } |
| newXfs.FillId = ix; |
| } |
| |
| //Named style reference |
| if (xfs.XfId > 0) { |
| var id = style.CellStyleXfs[xfs.XfId].Id; |
| var newId = CellStyleXfs.FindIndexById(id); |
| if (newId >= 0) { |
| newXfs.XfId = newId; |
| } else if (style._wb != _wb |
| && allwaysAdd |
| == false) //Not the same workbook, copy the namedstyle to the workbook or match the id |
| { |
| var nsFind = style.NamedStyles.ToDictionary(d => (d.StyleXfId)); |
| if (nsFind.ContainsKey(xfs.XfId)) { |
| var st = nsFind[xfs.XfId]; |
| if (NamedStyles.ExistsKey(st.Name)) { |
| newXfs.XfId = NamedStyles.FindIndexById(st.Name); |
| } else { |
| var ns = CreateNamedStyle(st.Name, st.Style); |
| newXfs.XfId = NamedStyles.Count - 1; |
| } |
| } |
| } |
| } |
| |
| int index; |
| if (isNamedStyle) { |
| index = CellStyleXfs.Add(newXfs.Id, newXfs); |
| } else { |
| if (allwaysAdd) { |
| index = CellXfs.Add(newXfs.Id, newXfs); |
| } else { |
| index = CellXfs.FindIndexById(newXfs.Id); |
| if (index < 0) { |
| index = CellXfs.Add(newXfs.Id, newXfs); |
| } |
| } |
| } |
| return index; |
| } |
| } |
| } |