Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ExportSymbolicDataAnalysisSolutions/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/3.1.3/EPPlus-3.1.3/ExcelStyles.cs @ 12094

Last change on this file since 12094 was 9580, checked in by sforsten, 12 years ago

#1730:

  • added SymbolicDataAnalysisExpressionExcelFormatter
  • changed modifiers in SymbolicExpressionTreeChart of methods SaveImageAsBitmap and SaveImageAsEmf to public
  • added menu item ExportSymbolicSolutionToExcelMenuItem to export a symbolic solution to an excel file
  • added EPPlus-3.1.3 to ExtLibs
File size: 34.6 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Jan Källman        Initial Release           2009-10-01
30 * Jan Källman        License changed GPL-->LGPL 2011-12-27
31 *******************************************************************************/
32using System;
33using System.Xml;
34using System.Collections.Generic;
35using draw=System.Drawing;
36using OfficeOpenXml.Style;
37using OfficeOpenXml.Style.XmlAccess;
38using OfficeOpenXml.Style.Dxf;
39using OfficeOpenXml.ConditionalFormatting;
40namespace OfficeOpenXml
41{
42  /// <summary>
43  /// Containts all shared cell styles for a workbook
44  /// </summary>
45    public sealed class ExcelStyles : XmlHelper
46    {
47        const string NumberFormatsPath = "d:styleSheet/d:numFmts";
48        const string FontsPath = "d:styleSheet/d:fonts";
49        const string FillsPath = "d:styleSheet/d:fills";
50        const string BordersPath = "d:styleSheet/d:borders";
51        const string CellStyleXfsPath = "d:styleSheet/d:cellStyleXfs";
52        const string CellXfsPath = "d:styleSheet/d:cellXfs";
53        const string CellStylesPath = "d:styleSheet/d:cellStyles";
54        const string dxfsPath = "d:styleSheet/d:dxfs";
55
56        //internal Dictionary<int, ExcelXfs> Styles = new Dictionary<int, ExcelXfs>();
57        XmlDocument _styleXml;
58        ExcelWorkbook _wb;
59        XmlNamespaceManager _nameSpaceManager;
60        internal int _nextDfxNumFmtID = 164;
61        internal ExcelStyles(XmlNamespaceManager NameSpaceManager, XmlDocument xml, ExcelWorkbook wb) :
62            base(NameSpaceManager, xml)
63        {       
64            _styleXml=xml;
65            _wb = wb;
66            _nameSpaceManager = NameSpaceManager;
67            SchemaNodeOrder = new string[] { "numFmts", "fonts", "fills", "borders", "cellStyleXfs", "cellXfs", "cellStyles", "dxfs" };
68            LoadFromDocument();
69        }
70        /// <summary>
71        /// Loads the style XML to memory
72        /// </summary>
73        private void LoadFromDocument()
74        {
75            //NumberFormats
76            ExcelNumberFormatXml.AddBuildIn(NameSpaceManager, NumberFormats);
77            XmlNode numNode = _styleXml.SelectSingleNode(NumberFormatsPath, _nameSpaceManager);
78            if (numNode != null)
79            {
80                foreach (XmlNode n in numNode)
81                {
82                    ExcelNumberFormatXml nf = new ExcelNumberFormatXml(_nameSpaceManager, n);
83                    NumberFormats.Add(nf.Id, nf);
84                    if (nf.NumFmtId >= NumberFormats.NextId) NumberFormats.NextId=nf.NumFmtId+1;
85                }
86            }
87
88            //Fonts
89            XmlNode fontNode = _styleXml.SelectSingleNode(FontsPath, _nameSpaceManager);
90            foreach (XmlNode n in fontNode)
91            {
92                ExcelFontXml f = new ExcelFontXml(_nameSpaceManager, n);
93                Fonts.Add(f.Id, f);
94            }
95
96            //Fills
97            XmlNode fillNode = _styleXml.SelectSingleNode(FillsPath, _nameSpaceManager);
98            foreach (XmlNode n in fillNode)
99            {
100                ExcelFillXml f;
101                if (n.FirstChild != null && n.FirstChild.LocalName == "gradientFill")
102                {
103                    f = new ExcelGradientFillXml(_nameSpaceManager, n);
104                }
105                else
106                {
107                    f = new ExcelFillXml(_nameSpaceManager, n);
108                }
109                Fills.Add(f.Id, f);
110            }
111
112            //Borders
113            XmlNode borderNode = _styleXml.SelectSingleNode(BordersPath, _nameSpaceManager);
114            foreach (XmlNode n in borderNode)
115            {
116                ExcelBorderXml b = new ExcelBorderXml(_nameSpaceManager, n);
117                Borders.Add(b.Id, b);
118            }
119
120            //cellStyleXfs
121            XmlNode styleXfsNode = _styleXml.SelectSingleNode(CellStyleXfsPath, _nameSpaceManager);
122            if (styleXfsNode != null)
123            {
124                foreach (XmlNode n in styleXfsNode)
125                {
126                    ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this);
127                    CellStyleXfs.Add(item.Id, item);
128                }
129            }
130
131            XmlNode styleNode = _styleXml.SelectSingleNode(CellXfsPath, _nameSpaceManager);
132            for (int i = 0; i < styleNode.ChildNodes.Count; i++)
133            {
134                XmlNode n = styleNode.ChildNodes[i];
135                ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this);
136                CellXfs.Add(item.Id, item);
137            }
138
139            //cellStyle
140            XmlNode namedStyleNode = _styleXml.SelectSingleNode(CellStylesPath, _nameSpaceManager);
141            if (namedStyleNode != null)
142            {
143                foreach (XmlNode n in namedStyleNode)
144                {
145                    ExcelNamedStyleXml item = new ExcelNamedStyleXml(_nameSpaceManager, n, this);
146                    NamedStyles.Add(item.Name, item);
147                }
148            }
149
150            //dxfsPath
151            XmlNode dxfsNode = _styleXml.SelectSingleNode(dxfsPath, _nameSpaceManager);
152            if (dxfsNode != null)
153            {
154                foreach (XmlNode x in dxfsNode)
155                {
156                    ExcelDxfStyleConditionalFormatting item = new ExcelDxfStyleConditionalFormatting(_nameSpaceManager, x, this);
157                    Dxfs.Add(item.Id, item);
158                }
159            }
160        }
161        internal ExcelStyle GetStyleObject(int Id,int PositionID, string Address)
162        {
163            if (Id < 0) Id = 0;
164            return new ExcelStyle(this, PropertyChange, PositionID, Address, Id);
165        }
166        /// <summary>
167        /// Handels changes of properties on the style objects
168        /// </summary>
169        /// <param name="sender"></param>
170        /// <param name="e"></param>
171        /// <returns></returns>
172        internal int PropertyChange(StyleBase sender, Style.StyleChangeEventArgs e)
173        {
174            var address = new ExcelAddressBase(e.Address);
175            var ws = _wb.Worksheets[e.PositionID];
176            Dictionary<int, int> styleCashe = new Dictionary<int, int>();
177            //Set single address
178            SetStyleAddress(sender, e, address, ws, ref styleCashe);
179            if (address.Addresses != null)
180            {
181                //Handle multiaddresses
182                foreach (var innerAddress in address.Addresses)
183                {
184                    SetStyleAddress(sender, e, innerAddress, ws, ref styleCashe);
185                }
186            }
187            return 0;
188        }
189
190        private void SetStyleAddress(StyleBase sender, Style.StyleChangeEventArgs e, ExcelAddressBase address, ExcelWorksheet ws, ref Dictionary<int, int> styleCashe)
191        {
192            if (address.Start.Column == 0 || address.Start.Row == 0)
193            {
194                throw (new Exception("error address"));
195            }
196            //Columns
197            else if (address.Start.Row == 1 && address.End.Row == ExcelPackage.MaxRows)
198            {
199                ExcelColumn column;
200                //Get the startcolumn
201                ulong colID = ExcelColumn.GetColumnID(ws.SheetID, address.Start.Column);
202                if (!ws._columns.ContainsKey(colID))
203                {
204                    column=ws.Column(address.Start.Column);
205                }
206                else
207                {
208                    column = ws._columns[colID] as ExcelColumn;
209                }
210
211                var index = ws._columns.IndexOf(colID);
212                while(column.ColumnMin <= address.End.Column)
213                {
214                    if (column.ColumnMax > address.End.Column)
215                    {
216                        var newCol = ws.CopyColumn(column, address.End.Column + 1, column.ColumnMax);
217                        column.ColumnMax = address.End.Column;
218                    }
219
220                    if (styleCashe.ContainsKey(column.StyleID))
221                    {
222                        column.StyleID = styleCashe[column.StyleID];
223                    }
224                    else
225                    {
226                        ExcelXfs st = CellXfs[column.StyleID];
227                        int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
228                        styleCashe.Add(column.StyleID, newId);
229                        column.StyleID = newId;
230                    }
231
232                    index++;
233                    if (index >= ws._columns.Count)
234                    {
235                        break;
236                    }
237                    else
238                    {
239                        column = (ws._columns[index] as ExcelColumn);
240                    }
241                }
242
243                if (column._columnMax < address.End.Column)
244                {
245                    var newCol = ws.Column(column._columnMax + 1) as ExcelColumn;
246                    newCol._columnMax = address.End.Column;
247
248                    if (styleCashe.ContainsKey(newCol.StyleID))
249                    {
250                        newCol.StyleID = styleCashe[newCol.StyleID];
251                    }
252                    else
253                    {
254                        ExcelXfs st = CellXfs[column.StyleID];
255                        int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
256                        styleCashe.Add(newCol.StyleID, newId);
257                        newCol.StyleID = newId;
258                    }
259                   
260                    //column._columnMax = address.End.Column;
261                }
262
263                //Set for individual cells in the spann. We loop all cells here since the cells are sorted with columns first.
264                foreach (ExcelCell cell in ws._cells)
265                {
266                    if (cell.Column >= address.Start.Column &&
267                       cell.Column <= address.End.Column)
268                    {
269                        if (styleCashe.ContainsKey(cell.StyleID))
270                        {
271                            cell.StyleID = styleCashe[cell.StyleID];
272                        }
273                        else
274                        {
275                            ExcelXfs st = CellXfs[cell.StyleID];
276                            int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
277                            styleCashe.Add(cell.StyleID, newId);
278                            cell.StyleID = newId;
279                        }
280                    }
281
282                }
283            }
284            //Rows
285            else if(address.Start.Column==1 && address.End.Column==ExcelPackage.MaxColumns)
286            {
287                for (int rowNum = address.Start.Row; rowNum <= address.End.Row; rowNum++)
288                {
289                    ExcelRow row = ws.Row(rowNum);
290                    if (row.StyleID == 0 && ws._columns.Count > 0)
291                    {
292                        //TODO: We should loop all columns here and change each cell. But for now we take style of column A.
293                        foreach (ExcelColumn column in ws._columns)
294                        {
295                            row.StyleID = column.StyleID;
296                            break;  //Get the first one and break.
297                        }
298
299                    }
300                    if (styleCashe.ContainsKey(row.StyleID))
301                    {
302                        row.StyleID = styleCashe[row.StyleID];
303                    }
304                    else
305                    {
306                        ExcelXfs st = CellXfs[row.StyleID];
307                        int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
308                        styleCashe.Add(row.StyleID, newId);
309                        row.StyleID = newId;
310                    }
311                }
312
313                //Get Start Cell
314                ulong rowID = ExcelRow.GetRowID(ws.SheetID, address.Start.Row);
315                int index = ws._cells.IndexOf(rowID);
316
317                index = ~index;
318                while (index < ws._cells.Count)
319                {                       
320                    var cell = ws._cells[index] as ExcelCell;
321                    if(cell.Row > address.End.Row)
322                    {
323                        break;
324                    }
325                    if (styleCashe.ContainsKey(cell.StyleID))
326                    {
327                        cell.StyleID = styleCashe[cell.StyleID];
328                    }
329                    else
330                    {
331                        ExcelXfs st = CellXfs[cell.StyleID];
332                        int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
333                        styleCashe.Add(cell.StyleID, newId);
334                        cell.StyleID = newId;
335                    }
336                    index++;
337                }
338            }
339            else             //Cellrange
340            {
341                for (int col = address.Start.Column; col <= address.End.Column; col++)
342                {
343                    for (int row = address.Start.Row; row <= address.End.Row; row++)
344                    {
345                        ExcelCell cell = ws.Cell(row, col);
346                        if (styleCashe.ContainsKey(cell.StyleID))
347                        {
348                            cell.StyleID = styleCashe[cell.StyleID];
349                        }
350                        else
351                        {
352                            ExcelXfs st = CellXfs[cell.StyleID];
353                            int newId = st.GetNewID(CellXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
354                            styleCashe.Add(cell.StyleID, newId);
355                            cell.StyleID = newId;
356                        }
357                    }
358                }           
359            }
360        }
361        /// <summary>
362        /// Handles property changes on Named styles.
363        /// </summary>
364        /// <param name="sender"></param>
365        /// <param name="e"></param>
366        /// <returns></returns>
367        internal int NamedStylePropertyChange(StyleBase sender, Style.StyleChangeEventArgs e)
368        {
369
370            int index = NamedStyles.FindIndexByID(e.Address);
371            if (index >= 0)
372            {
373                int newId = CellStyleXfs[NamedStyles[index].StyleXfId].GetNewID(CellStyleXfs, sender, e.StyleClass, e.StyleProperty, e.Value);
374                int prevIx=NamedStyles[index].StyleXfId;
375                NamedStyles[index].StyleXfId = newId;
376                NamedStyles[index].Style.Index = newId;
377
378                NamedStyles[index].XfId = int.MinValue;
379                foreach (var style in CellXfs)
380                {
381                    if (style.XfId == prevIx)
382                    {
383                        style.XfId = newId;
384                    }
385                }
386            }
387            return 0;
388        }
389        public ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats = new ExcelStyleCollection<ExcelNumberFormatXml>();
390        public ExcelStyleCollection<ExcelFontXml> Fonts = new ExcelStyleCollection<ExcelFontXml>();
391        public ExcelStyleCollection<ExcelFillXml> Fills = new ExcelStyleCollection<ExcelFillXml>();
392        public ExcelStyleCollection<ExcelBorderXml> Borders = new ExcelStyleCollection<ExcelBorderXml>();
393        public ExcelStyleCollection<ExcelXfs> CellStyleXfs = new ExcelStyleCollection<ExcelXfs>();
394        public ExcelStyleCollection<ExcelXfs> CellXfs = new ExcelStyleCollection<ExcelXfs>();
395        public ExcelStyleCollection<ExcelNamedStyleXml> NamedStyles = new ExcelStyleCollection<ExcelNamedStyleXml>();
396        public ExcelStyleCollection<ExcelDxfStyleConditionalFormatting> Dxfs = new ExcelStyleCollection<ExcelDxfStyleConditionalFormatting>();
397       
398        internal string Id
399        {
400            get { return ""; }
401        }
402
403        public ExcelNamedStyleXml CreateNamedStyle(string name)
404        {
405            return CreateNamedStyle(name, null);
406        }
407        public ExcelNamedStyleXml CreateNamedStyle(string name, ExcelStyle Template)
408        {
409            if (_wb.Styles.NamedStyles.ExistsKey(name))
410            {
411                throw new Exception(string.Format("Key {0} already exists in collection", name));
412            }
413
414            ExcelNamedStyleXml style;
415            style = new ExcelNamedStyleXml(NameSpaceManager, this);
416            int xfIdCopy, positionID;
417            ExcelStyles styles;
418            if (Template == null)
419            {
420//                style.Style = new ExcelStyle(this, NamedStylePropertyChange, -1, name, 0);
421                xfIdCopy = 0;
422                positionID = -1;
423                styles = this;
424            }
425            else
426            {
427                if (Template.PositionID < 0 && Template.Styles==this)
428                {
429                    xfIdCopy = Template.Index;
430                    positionID=Template.PositionID;
431                    styles = this;
432                    //style.Style = new ExcelStyle(this, NamedStylePropertyChange, Template.PositionID, name, Template.Index);
433                    //style.StyleXfId = Template.Index;
434                }
435                else
436                {
437                    xfIdCopy = Template.XfId;
438                    positionID = -1;
439                    styles = Template.Styles;
440                }
441            }
442            //Clone namedstyle
443            int styleXfId = CloneStyle(styles, xfIdCopy, true);
444            //Close cells style
445            CellStyleXfs[styleXfId].XfId = CellStyleXfs.Count-1;
446            int xfid = CloneStyle(styles, xfIdCopy, false, true); //Always add a new style (We create a new named style here)
447            CellXfs[xfid].XfId = styleXfId;
448            style.Style = new ExcelStyle(this, NamedStylePropertyChange, positionID, name, styleXfId);
449            style.StyleXfId = styleXfId;
450           
451            style.Name = name;
452            int ix =_wb.Styles.NamedStyles.Add(style.Name, style);
453            style.Style.SetIndex(ix);
454            //style.Style.XfId = ix;
455            return style;
456        }
457        public void UpdateXml()
458        {
459            RemoveUnusedStyles();
460
461            //NumberFormat
462            XmlNode nfNode=_styleXml.SelectSingleNode(NumberFormatsPath, _nameSpaceManager);
463            if (nfNode == null)
464            {
465                CreateNode(NumberFormatsPath, true);
466                nfNode = _styleXml.SelectSingleNode(NumberFormatsPath, _nameSpaceManager);
467            }
468            else
469            {
470                nfNode.RemoveAll();               
471            }
472
473            int count = 0;
474            int normalIx = NamedStyles.FindIndexByID("Normal");
475            if (NamedStyles.Count > 0 && normalIx>=0 && NamedStyles[normalIx].Style.Numberformat.NumFmtID >= 164)
476            {
477                ExcelNumberFormatXml nf = NumberFormats[NumberFormats.FindIndexByID(NamedStyles[normalIx].Style.Numberformat.Id)];
478                nfNode.AppendChild(nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage.schemaMain)));
479                nf.newID = count++;
480            }
481            foreach (ExcelNumberFormatXml nf in NumberFormats)
482            {
483                if(!nf.BuildIn /*&& nf.newID<0*/) //Buildin formats are not updated.
484                {
485                    nfNode.AppendChild(nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage.schemaMain)));
486                    nf.newID = count;
487                    count++;
488                }
489            }
490            (nfNode as XmlElement).SetAttribute("count", count.ToString());
491
492            //Font
493            count=0;
494            XmlNode fntNode = _styleXml.SelectSingleNode(FontsPath, _nameSpaceManager);
495            fntNode.RemoveAll();
496
497            //Normal should be first in the collection
498            if (NamedStyles.Count > 0 && normalIx >= 0 && NamedStyles[normalIx].Style.Font.Index > 0)
499            {
500                ExcelFontXml fnt = Fonts[NamedStyles[normalIx].Style.Font.Index];
501                fntNode.AppendChild(fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage.schemaMain)));
502                fnt.newID = count++;
503            }
504
505            foreach (ExcelFontXml fnt in Fonts)
506            {
507                if (fnt.useCnt > 0/* && fnt.newID<0*/)
508                {
509                    fntNode.AppendChild(fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage.schemaMain)));
510                    fnt.newID = count;
511                    count++;
512                }
513            }
514            (fntNode as XmlElement).SetAttribute("count", count.ToString());
515
516
517            //Fills
518            count = 0;
519            XmlNode fillsNode = _styleXml.SelectSingleNode(FillsPath, _nameSpaceManager);
520            fillsNode.RemoveAll();
521            Fills[0].useCnt = 1;    //Must exist (none); 
522            Fills[1].useCnt = 1;    //Must exist (gray125);
523            foreach (ExcelFillXml fill in Fills)
524            {
525                if (fill.useCnt > 0)
526                {
527                    fillsNode.AppendChild(fill.CreateXmlNode(_styleXml.CreateElement("fill", ExcelPackage.schemaMain)));
528                    fill.newID = count;
529                    count++;
530                }
531            }
532
533            (fillsNode as XmlElement).SetAttribute("count", count.ToString());
534
535            //Borders
536            count = 0;
537            XmlNode bordersNode = _styleXml.SelectSingleNode(BordersPath, _nameSpaceManager);
538            bordersNode.RemoveAll();
539            Borders[0].useCnt = 1;    //Must exist blank;
540            foreach (ExcelBorderXml border in Borders)
541            {
542                if (border.useCnt > 0)
543                {
544                    bordersNode.AppendChild(border.CreateXmlNode(_styleXml.CreateElement("border", ExcelPackage.schemaMain)));
545                    border.newID = count;
546                    count++;
547                }
548            }
549            (bordersNode as XmlElement).SetAttribute("count", count.ToString());
550
551            XmlNode styleXfsNode = _styleXml.SelectSingleNode(CellStyleXfsPath, _nameSpaceManager);
552            if (styleXfsNode == null && NamedStyles.Count > 0)
553            {
554                CreateNode(CellStyleXfsPath);
555                styleXfsNode = _styleXml.SelectSingleNode(CellStyleXfsPath, _nameSpaceManager);
556            }
557            if (NamedStyles.Count > 0)
558            {
559                styleXfsNode.RemoveAll();
560            }
561            //NamedStyles
562            count = normalIx > -1 ? 1 : 0;  //If we have a normal style, we make sure it's added first.
563
564            XmlNode cellStyleNode = _styleXml.SelectSingleNode(CellStylesPath, _nameSpaceManager);
565            if(cellStyleNode!=null)
566            {
567                cellStyleNode.RemoveAll();
568            }
569            XmlNode cellXfsNode = _styleXml.SelectSingleNode(CellXfsPath, _nameSpaceManager);
570            cellXfsNode.RemoveAll();
571
572            if (NamedStyles.Count > 0 && normalIx >= 0)
573            {
574                NamedStyles[normalIx].newID = 0;
575                AddNamedStyle(0, styleXfsNode, cellXfsNode, NamedStyles[normalIx]);
576            }
577            foreach (ExcelNamedStyleXml style in NamedStyles)
578            {
579                if (style.Name.ToLower() != "normal")
580                {
581                    style.newID = count;
582                    AddNamedStyle(count++, styleXfsNode, cellXfsNode, style);
583                }
584                else
585                {
586                    style.newID = 0;
587                }
588                cellStyleNode.AppendChild(style.CreateXmlNode(_styleXml.CreateElement("cellStyle", ExcelPackage.schemaMain)));
589            }
590            if (cellStyleNode!=null) (cellStyleNode as XmlElement).SetAttribute("count", count.ToString());
591            if (styleXfsNode != null) (styleXfsNode as XmlElement).SetAttribute("count", count.ToString());
592
593            //CellStyle
594            int xfix = 0;
595            foreach (ExcelXfs xf in CellXfs)
596            {
597                if (xf.useCnt > 0 && !(normalIx == xfix))
598                {
599                    cellXfsNode.AppendChild(xf.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage.schemaMain)));
600                    xf.newID = count;
601                    count++;
602                }
603                xfix++;
604            }
605            (cellXfsNode as XmlElement).SetAttribute("count", count.ToString());
606
607            //Set dxf styling for conditional Formatting
608            XmlNode dxfsNode = _styleXml.SelectSingleNode(dxfsPath, _nameSpaceManager);
609            foreach (var ws in _wb.Worksheets)
610            {
611                foreach (var cf in ws.ConditionalFormatting)
612                {
613                    if (cf.Style.HasValue)
614                    {
615                        int ix = Dxfs.FindIndexByID(cf.Style.Id);
616                        if (ix < 0)
617                        {
618                            ((ExcelConditionalFormattingRule)cf).DxfId = Dxfs.Count;
619                            Dxfs.Add(cf.Style.Id, cf.Style);
620                            var elem = ((XmlDocument)TopNode).CreateElement("d", "dxf", ExcelPackage.schemaMain);
621                            cf.Style.CreateNodes(new XmlHelperInstance(NameSpaceManager, elem), "");
622                            dxfsNode.AppendChild(elem);
623                        }
624                        else
625                        {
626                            ((ExcelConditionalFormattingRule)cf).DxfId = ix;
627                        }
628                    }
629                }
630            }
631        }
632
633        private void AddNamedStyle(int id, XmlNode styleXfsNode,XmlNode cellXfsNode, ExcelNamedStyleXml style)
634        {
635            var styleXfs = CellStyleXfs[style.StyleXfId];
636            styleXfsNode.AppendChild(styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage.schemaMain), true));
637            styleXfs.newID = id;
638            styleXfs.XfId = style.StyleXfId;
639
640            var ix = CellXfs.FindIndexByID(styleXfs.Id);
641            if (ix < 0)
642            {
643                cellXfsNode.AppendChild(styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage.schemaMain)));
644            }
645            else
646            {
647                if (id < 0) CellXfs[ix].XfId = id;
648                cellXfsNode.AppendChild(CellXfs[ix].CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage.schemaMain)));
649                CellXfs[ix].useCnt = 0;
650                CellXfs[ix].newID = id;
651
652            }
653
654            if (style.XfId >= 0)
655                style.XfId = CellXfs[style.XfId].newID;
656            else
657                style.XfId = 0;
658        }
659
660        private void RemoveUnusedStyles()
661        {
662            CellXfs[0].useCnt = 1; //First item is allways used.
663            foreach (ExcelWorksheet sheet in _wb.Worksheets)
664            {
665                foreach (ExcelCell cell in sheet._cells) //sheet._cells.Values
666                {
667                    CellXfs[cell.GetCellStyleID()].useCnt++;
668                }
669                foreach(ExcelRow row in sheet._rows)
670                {
671                    CellXfs[row.StyleID].useCnt++;
672                }
673                foreach (ExcelColumn col in sheet._columns)
674                {
675                    if(col.StyleID>=0) CellXfs[col.StyleID].useCnt++;
676                }
677            }
678            foreach (ExcelNamedStyleXml ns in NamedStyles)
679            {
680                CellStyleXfs[ns.StyleXfId].useCnt++;
681            }
682
683            foreach (ExcelXfs xf in CellXfs)
684            {
685                if (xf.useCnt > 0)
686                {
687                    if (xf.FontId >= 0) Fonts[xf.FontId].useCnt++;
688                    if (xf.FillId >= 0) Fills[xf.FillId].useCnt++;
689                    if (xf.BorderId >= 0) Borders[xf.BorderId].useCnt++;
690                }
691            }
692            foreach (ExcelXfs xf in CellStyleXfs)
693            {
694                if (xf.useCnt > 0)
695                {
696                    if (xf.FontId >= 0) Fonts[xf.FontId].useCnt++;
697                    if (xf.FillId >= 0) Fills[xf.FillId].useCnt++;
698                    if (xf.BorderId >= 0) Borders[xf.BorderId].useCnt++;                   
699                }
700            }
701        }
702        internal int GetStyleIdFromName(string Name)
703        {
704            int i = NamedStyles.FindIndexByID(Name);
705            if (i >= 0)
706            {
707                int id = NamedStyles[i].XfId;
708                if (id < 0)
709                {
710                    int styleXfId=NamedStyles[i].StyleXfId;
711                    ExcelXfs newStyle = CellStyleXfs[styleXfId].Copy();
712                    newStyle.XfId = styleXfId;
713                    id = CellXfs.FindIndexByID(newStyle.Id);
714                    if (id < 0)
715                    {
716                        id = CellXfs.Add(newStyle.Id, newStyle);
717                    }
718                    NamedStyles[i].XfId=id;
719                }
720                return id;
721            }
722            else
723            {
724                return 0;
725                //throw(new Exception("Named style does not exist"));                 
726            }
727        }
728   #region XmlHelpFunctions
729        private int GetXmlNodeInt(XmlNode node)
730        {
731            int i;
732            if (int.TryParse(GetXmlNode(node), out i))
733            {
734                return i;
735            }
736            else
737            {
738                return 0;
739            }
740        }
741        private string GetXmlNode(XmlNode node)
742        {
743            if (node == null)
744            {
745                return "";
746            }
747            if (node.Value != null)
748            {
749                return node.Value;
750            }
751            else
752            {
753                return "";
754            }
755        }
756
757#endregion
758        internal int CloneStyle(ExcelStyles style, int styleID)
759        {
760            return CloneStyle(style, styleID, false, false);
761        }
762        internal int CloneStyle(ExcelStyles style, int styleID, bool isNamedStyle)
763        {
764            return CloneStyle(style, styleID, isNamedStyle, false);
765        }
766        internal int CloneStyle(ExcelStyles style, int styleID, bool isNamedStyle, bool allwaysAdd)
767        {
768            ExcelXfs xfs;
769            if (isNamedStyle)
770            {
771                xfs = style.CellStyleXfs[styleID];
772            }
773            else
774            {
775                xfs = style.CellXfs[styleID];
776            }
777            ExcelXfs newXfs=xfs.Copy(this);
778            //Numberformat
779            if (xfs.NumberFormatId > 0)
780            {
781                string format="";
782                foreach (var fmt in style.NumberFormats)
783                {
784                    if (fmt.NumFmtId == xfs.NumberFormatId)
785                    {
786                        format=fmt.Format;
787                        break;
788                    }
789                }
790                int ix=NumberFormats.FindIndexByID(format);
791                if (ix<0)
792                {
793                    ExcelNumberFormatXml item = new ExcelNumberFormatXml(NameSpaceManager) { Format = format, NumFmtId = NumberFormats.NextId++ };
794                    NumberFormats.Add(format, item);
795                    ix=item.NumFmtId;
796                }
797                newXfs.NumberFormatId= ix;
798            }
799
800            //Font
801            if (xfs.FontId > -1)
802            {
803                int ix=Fonts.FindIndexByID(xfs.Font.Id);
804                if (ix<0)
805                {
806                    ExcelFontXml item = style.Fonts[xfs.FontId].Copy();
807                    ix=Fonts.Add(xfs.Font.Id, item);
808                }
809                newXfs.FontId=ix;
810            }
811
812            //Border
813            if (xfs.BorderId > -1)
814            {
815                int ix = Borders.FindIndexByID(xfs.Border.Id);
816                if (ix < 0)
817                {
818                    ExcelBorderXml item = style.Borders[xfs.BorderId].Copy();
819                    ix = Borders.Add(xfs.Border.Id, item);
820                }
821                newXfs.BorderId = ix;
822            }
823
824            //Fill
825            if (xfs.FillId > -1)
826            {
827                int ix = Fills.FindIndexByID(xfs.Fill.Id);
828                if (ix < 0)
829                {
830                    var item = style.Fills[xfs.FillId].Copy();
831                    ix = Fills.Add(xfs.Fill.Id, item);
832                }
833                newXfs.FillId = ix;
834            }
835
836            //Named style reference
837            if (xfs.XfId > 0)
838            {
839                var id = style.CellStyleXfs[xfs.XfId].Id;
840                var newId = CellStyleXfs.FindIndexByID(id);
841                //if (newId < 0)
842                //{
843                   
844                //    newXfs.XfId = CloneStyle(style, xfs.XfId, true);
845                //}
846                //else
847                //{
848                    newXfs.XfId = newId;
849                //}
850            }
851
852            int index;
853            if (isNamedStyle)
854            {
855                index = CellStyleXfs.Add(newXfs.Id, newXfs);
856            }
857            else
858            {
859                if (allwaysAdd)
860                {
861                    index = CellXfs.Add(newXfs.Id, newXfs);
862                }
863                else
864                {
865                    index = CellXfs.FindIndexByID(newXfs.Id);
866                    if (index < 0)
867                    {
868                        index = CellXfs.Add(newXfs.Id, newXfs);
869                    }
870                }
871            }
872            return index;
873        }
874    }
875}
Note: See TracBrowser for help on using the repository browser.