NanoXLSX.Core 3.0.0-rc.3
Loading...
Searching...
No Matches
StyleManager.cs
1/*
2 * NanoXLSX is a small .NET library to generate and read XLSX (Microsoft Excel 2007 or newer) files in an easy and native way
3 * Copyright Raphael Stoeckli © 2025
4 * This library is licensed under the MIT License.
5 * You find a copy of the license in project folder or on: http://opensource.org/licenses/MIT
6 */
7
8using System;
9using System.Collections.Generic;
10
11namespace NanoXLSX.Styles
12{
17 internal class StyleManager
18 {
19 #region privateFields
20 private List<AbstractStyle> borders;
21 private List<AbstractStyle> cellXfs;
22 private List<AbstractStyle> fills;
23 private List<AbstractStyle> fonts;
24 private List<AbstractStyle> numberFormats;
25 private List<AbstractStyle> styles;
26 #endregion
27
28 #region constructors
32 public StyleManager()
33 {
34 borders = new List<AbstractStyle>();
35 cellXfs = new List<AbstractStyle>();
36 fills = new List<AbstractStyle>();
37 fonts = new List<AbstractStyle>();
38 numberFormats = new List<AbstractStyle>();
39 styles = new List<AbstractStyle>();
40 }
41 #endregion
42
43 #region methods
44
51 private static AbstractStyle GetComponentByHash(ref List<AbstractStyle> list, int hash)
52 {
53 int len = list.Count;
54 for (int i = 0; i < len; i++)
55 {
56 if (list[i].GetHashCode() == hash)
57 {
58 return list[i];
59 }
60 }
61 return null;
62 }
63
68 public Border[] GetBorders()
69 {
70 return Array.ConvertAll(borders.ToArray(), x => (Border)x);
71 }
72
77 public int GetBorderStyleNumber()
78 {
79 return borders.Count;
80 }
81
82
83
84 /* ****************************** */
85
90 public Fill[] GetFills()
91 {
92 return Array.ConvertAll(fills.ToArray(), x => (Fill)x);
93 }
94
99 public int GetFillStyleNumber()
100 {
101 return fills.Count;
102 }
103
104 /* ****************************** */
105
110 public Font[] GetFonts()
111 {
112 return Array.ConvertAll(fonts.ToArray(), x => (Font)x);
113 }
114
119 public int GetFontStyleNumber()
120 {
121 return fonts.Count;
122 }
123
124 /* ****************************** */
125
130 public NumberFormat[] GetNumberFormats()
131 {
132 return Array.ConvertAll(numberFormats.ToArray(), x => (NumberFormat)x);
133 }
134
139 public int GetNumberFormatStyleNumber()
140 {
141 return numberFormats.Count;
142 }
143
144 /* ****************************** */
145
150 public Style[] GetStyles()
151 {
152 return Array.ConvertAll(styles.ToArray(), x => (Style)x);
153 }
154
159 public int GetStyleNumber()
160 {
161 return styles.Count;
162 }
163
164 /* ****************************** */
165
166
172 public Style AddStyle(Style style)
173 {
174 int hash = AddStyleComponent(style);
175 return (Style)GetComponentByHash(ref styles, hash);
176 }
177
184 private int AddStyleComponent(AbstractStyle style, int? id)
185 {
186 style.InternalID = id;
187 return AddStyleComponent(style);
188 }
189
195 private int AddStyleComponent(AbstractStyle style)
196 {
197 int hash = style.GetHashCode();
198 if (style.GetType() == typeof(Border))
199 {
200 if (GetComponentByHash(ref borders, hash) == null)
201 { borders.Add(style); }
202 Reorganize(ref borders);
203 }
204 else if (style.GetType() == typeof(CellXf))
205 {
206 if (GetComponentByHash(ref cellXfs, hash) == null)
207 { cellXfs.Add(style); }
208 Reorganize(ref cellXfs);
209 }
210 else if (style.GetType() == typeof(Fill))
211 {
212 if (GetComponentByHash(ref fills, hash) == null)
213 { fills.Add(style); }
214 Reorganize(ref fills);
215 }
216 else if (style.GetType() == typeof(Font))
217 {
218 if (GetComponentByHash(ref fonts, hash) == null)
219 { fonts.Add(style); }
220 Reorganize(ref fonts);
221 }
222 else if (style.GetType() == typeof(NumberFormat))
223 {
224 if (GetComponentByHash(ref numberFormats, hash) == null)
225 { numberFormats.Add(style); }
226 Reorganize(ref numberFormats);
227 }
228 else if (style.GetType() == typeof(Style))
229 {
230 Style s = (Style)style;
231 if (GetComponentByHash(ref styles, hash) == null)
232 {
233 int? id;
234 if (!s.InternalID.HasValue)
235 {
236 id = int.MaxValue;
237 s.InternalID = id;
238 }
239 else
240 {
241 id = s.InternalID.Value;
242 }
243 int temp = AddStyleComponent(s.CurrentBorder, id);
244 s.CurrentBorder = (Border)GetComponentByHash(ref borders, temp);
245 temp = AddStyleComponent(s.CurrentCellXf, id);
246 s.CurrentCellXf = (CellXf)GetComponentByHash(ref cellXfs, temp);
247 temp = AddStyleComponent(s.CurrentFill, id);
248 s.CurrentFill = (Fill)GetComponentByHash(ref fills, temp);
249 temp = AddStyleComponent(s.CurrentFont, id);
250 s.CurrentFont = (Font)GetComponentByHash(ref fonts, temp);
251 temp = AddStyleComponent(s.CurrentNumberFormat, id);
252 s.CurrentNumberFormat = (NumberFormat)GetComponentByHash(ref numberFormats, temp);
253 styles.Add(s);
254 }
255 Reorganize(ref styles);
256 hash = s.GetHashCode();
257 }
258 return hash;
259 }
260
266 internal static StyleManager GetManagedStyles(Workbook workbook)
267 {
268 StyleManager styleManager = new StyleManager();
269 styleManager.AddStyle(new Style("default", 0, true));
270 Style borderStyle = new Style("default_border_style", 1, true)
271 {
272 CurrentBorder = BasicStyles.DottedFill_0_125.CurrentBorder,
273 CurrentFill = BasicStyles.DottedFill_0_125.CurrentFill
274 };
275 styleManager.AddStyle(borderStyle);
276
277 for (int i = 0; i < workbook.Worksheets.Count; i++)
278 {
279 foreach (KeyValuePair<string, Cell> cell in workbook.Worksheets[i].Cells)
280 {
281 if (cell.Value.CellStyle != null)
282 {
283 Style resolvedStyle = styleManager.AddStyle(cell.Value.CellStyle);
284 workbook.Worksheets[i].Cells[cell.Key].SetStyle(resolvedStyle, true);
285 }
286 }
287 foreach (KeyValuePair<int, Column> column in workbook.Worksheets[i].Columns)
288 {
289 if (column.Value.DefaultColumnStyle != null)
290 {
291 Style resolvedStyle = styleManager.AddStyle(column.Value.DefaultColumnStyle);
292 workbook.Worksheets[i].Columns[column.Key].SetDefaultColumnStyle(resolvedStyle, true);
293 }
294 }
295 }
296 return styleManager;
297 }
298
303 private static void Reorganize(ref List<AbstractStyle> list)
304 {
305 int len = list.Count;
306 list.Sort();
307 int id = 0;
308 for (int i = 0; i < len; i++)
309 {
310 list[i].InternalID = id;
311 id++;
312 }
313 }
314 #endregion
315 }
316
317}