NanoXLSX.Reader 3.0.0-rc.3
Loading...
Searching...
No Matches
StyleReader.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
9{
10 using System;
11 using System.IO;
12 using System.Xml;
13 using System.Xml.Linq;
14 using NanoXLSX.Colors;
15 using NanoXLSX.Interfaces.Plugin;
16 using NanoXLSX.Interfaces.Reader;
17 using NanoXLSX.Registry;
18 using NanoXLSX.Registry.Attributes;
19 using NanoXLSX.Styles;
20 using NanoXLSX.Themes;
21 using NanoXLSX.Utils;
22 using static NanoXLSX.Styles.Border;
23 using static NanoXLSX.Styles.CellXf;
24 using static NanoXLSX.Styles.Font;
25 using static NanoXLSX.Styles.NumberFormat;
26 using static NanoXLSX.Themes.Theme;
27 using IOException = Exceptions.IOException;
28
32 [NanoXlsxPlugIn(PlugInUUID = PlugInUUID.StyleReader)]
33 public class StyleReader : IPluginReader
34 {
35
36 private MemoryStream stream;
37 private StyleReaderContainer styleReaderContainer;
38
39 #region properties
43 public Workbook Workbook { get; set; }
44 #endregion
45
46 #region constructors
50 public StyleReader()
51 {
52 }
53 #endregion
54
55 #region methods
59 public void Init(MemoryStream stream, Workbook workbook, IOptions readerOptions)
60 {
61 this.stream = stream;
62 this.Workbook = workbook;
63 }
64
69 public void Execute()
70 {
71 this.styleReaderContainer = new StyleReaderContainer();
72 try
73 {
74 using (stream) // Close after processing
75 {
76 XmlDocument xr = new XmlDocument() { XmlResolver = null };
77 using (XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { XmlResolver = null }))
78 {
79 xr.Load(reader);
80 foreach (XmlNode node in xr.DocumentElement.ChildNodes)
81 {
82 if (node.LocalName.Equals("numfmts", StringComparison.OrdinalIgnoreCase)) // Handles custom number formats
83 {
84 GetNumberFormats(node);
85 }
86 else if (node.LocalName.Equals("borders", StringComparison.OrdinalIgnoreCase)) // Handles borders
87 {
88 GetBorders(node);
89 }
90 else if (node.LocalName.Equals("fills", StringComparison.OrdinalIgnoreCase)) // Handles fills
91 {
92 GetFills(node);
93 }
94 else if (node.LocalName.Equals("fonts", StringComparison.OrdinalIgnoreCase)) // Handles fonts
95 {
96 GetFonts(node);
97 }
98 else if (node.LocalName.Equals("colors", StringComparison.OrdinalIgnoreCase)) // Handles MRU colors
99 {
100 GetColors(node);
101 }
102 // TODO: Implement other style components
103 }
104 foreach (XmlNode node in xr.DocumentElement.ChildNodes) // Redo for composition after all style parts are gathered; standard number formats
105 {
106 if (node.LocalName.Equals("cellxfs", StringComparison.OrdinalIgnoreCase))
107 {
108 GetCellXfs(node);
109 }
110 }
111 HandleMruColors();
112 RederPlugInHandler.HandleInlineQueuePlugins(ref stream, Workbook, PlugInUUID.StyleInlineReader);
113 }
114 }
115 Workbook.AuxiliaryData.SetData(PlugInUUID.StyleReader, PlugInUUID.StyleEntity, styleReaderContainer);
116 }
117 catch (Exception ex)
118 {
119 throw new IOException("The XML entry could not be read from the input stream. Please see the inner exception:", ex);
120 }
121 }
122
126 private void HandleMruColors()
127 {
128 if (styleReaderContainer.GetMruColors().Count > 0)
129 {
130 foreach (string color in styleReaderContainer.GetMruColors())
131 {
132 Workbook.AddMruColor(color);
133 }
134 }
135 }
136
141 private void GetNumberFormats(XmlNode node)
142 {
143 foreach (XmlNode childNode in node.ChildNodes)
144 {
145 if (childNode.LocalName.Equals("numfmt", StringComparison.OrdinalIgnoreCase))
146 {
147 NumberFormat numberFormat = new NumberFormat();
148 int id = ParserUtils.ParseInt(ReaderUtils.GetAttribute(childNode, "numFmtId")); // Default will (justified) throw an exception
149 string code = ReaderUtils.GetAttribute(childNode, "formatCode", string.Empty);
150 numberFormat.CustomFormatID = id;
151 numberFormat.Number = FormatNumber.Custom;
152 numberFormat.InternalID = id;
153 numberFormat.CustomFormatCode = code;
154 this.styleReaderContainer.AddStyleComponent(numberFormat);
155 }
156 }
157 }
158
163 private void GetBorders(XmlNode node)
164 {
165 foreach (XmlNode border in node.ChildNodes)
166 {
167 Border borderStyle = new Border();
168 string diagonalDown = ReaderUtils.GetAttribute(border, "diagonalDown");
169 string diagonalUp = ReaderUtils.GetAttribute(border, "diagonalUp");
170 if (diagonalDown != null)
171 {
172 int value = ParserUtils.ParseBinaryBool(diagonalDown);
173 if (value == 1)
174 {
175 borderStyle.DiagonalDown = true;
176 }
177 }
178 if (diagonalUp != null)
179 {
180 int value = ParserUtils.ParseBinaryBool(diagonalUp);
181 if (value == 1)
182 {
183 borderStyle.DiagonalUp = true;
184 }
185 }
186 XmlNode innerNode = ReaderUtils.GetChildNode(border, "diagonal");
187 if (innerNode != null)
188 {
189 borderStyle.DiagonalStyle = ParseBorderStyle(innerNode);
190 borderStyle.DiagonalColor = GetColor(innerNode, Border.DefaultBorderColor);
191 }
192 innerNode = ReaderUtils.GetChildNode(border, "top");
193 if (innerNode != null)
194 {
195 borderStyle.TopStyle = ParseBorderStyle(innerNode);
196 borderStyle.TopColor = GetColor(innerNode, Border.DefaultBorderColor);
197 }
198 innerNode = ReaderUtils.GetChildNode(border, "bottom");
199 if (innerNode != null)
200 {
201 borderStyle.BottomStyle = ParseBorderStyle(innerNode);
202 borderStyle.BottomColor = GetColor(innerNode, Border.DefaultBorderColor);
203 }
204 innerNode = ReaderUtils.GetChildNode(border, "left");
205 if (innerNode != null)
206 {
207 borderStyle.LeftStyle = ParseBorderStyle(innerNode);
208 borderStyle.LeftColor = GetColor(innerNode, Border.DefaultBorderColor);
209 }
210 innerNode = ReaderUtils.GetChildNode(border, "right");
211 if (innerNode != null)
212 {
213 borderStyle.RightStyle = ParseBorderStyle(innerNode);
214 borderStyle.RightColor = GetColor(innerNode, Border.DefaultBorderColor);
215 }
216 borderStyle.InternalID = this.styleReaderContainer.GetNextBorderId();
217 this.styleReaderContainer.AddStyleComponent(borderStyle);
218 }
219 }
220
226 private static StyleValue ParseBorderStyle(XmlNode innerNode)
227 {
228 string value = ReaderUtils.GetAttribute(innerNode, "style");
229 if (value != null)
230 {
231 return Border.GetStyleEnum(value);
232 }
233 return StyleValue.None;
234 }
235
240 private void GetFills(XmlNode node)
241 {
242 foreach (XmlNode fill in node.ChildNodes)
243 {
244 Fill fillStyle = new Fill();
245 XmlNode innerNode = ReaderUtils.GetChildNode(fill, "patternFill");
246 if (innerNode != null)
247 {
248 string pattern = ReaderUtils.GetAttribute(innerNode, "patternType", string.Empty);
249 fillStyle.PatternFill = Fill.GetPatternEnum(pattern);
250
251 // Read fgColor
252 XmlNode fgColorNode = ReaderUtils.GetChildNode(innerNode, "fgColor");
253 if (fgColorNode != null)
254 {
255 fillStyle.ForegroundColor = ReadColorFromNode(fgColorNode);
256 }
257
258 // Read bgColor
259 XmlNode bgColorNode = ReaderUtils.GetChildNode(innerNode, "bgColor");
260 if (bgColorNode != null)
261 {
262 fillStyle.BackgroundColor = ReadColorFromNode(bgColorNode);
263 }
264 }
265 fillStyle.InternalID = this.styleReaderContainer.GetNextFillId();
266 this.styleReaderContainer.AddStyleComponent(fillStyle);
267 }
268 }
269
275 private Color ReadColorFromNode(XmlNode colorNode)
276 {
277 // Check for auto attribute
278 string autoAttr = ReaderUtils.GetAttribute(colorNode, "auto");
279 if (!string.IsNullOrEmpty(autoAttr) && ParserUtils.ParseBinaryBool(autoAttr) == 1)
280 {
281 return Color.CreateAuto();
282 }
283
284 // Check for rgb attribute
285 string rgbAttr = ReaderUtils.GetAttribute(colorNode, "rgb");
286 if (!string.IsNullOrEmpty(rgbAttr))
287 {
288 return Color.CreateRgb(rgbAttr);
289 }
290
291 // Check for indexed attribute
292 string indexedAttr = ReaderUtils.GetAttribute(colorNode, "indexed");
293 if (!string.IsNullOrEmpty(indexedAttr))
294 {
295 return Color.CreateIndexed(ParserUtils.ParseInt(indexedAttr));
296 }
297
298 // Check for theme attribute
299 string themeAttr = ReaderUtils.GetAttribute(colorNode, "theme");
300 if (!string.IsNullOrEmpty(themeAttr))
301 {
302 int themeIndex = ParserUtils.ParseInt(themeAttr);
303 // Check for optional tint attribute
304 string tintAttr = ReaderUtils.GetAttribute(colorNode, "tint");
305 double? tint = null;
306 if (!string.IsNullOrEmpty(tintAttr))
307 {
308 tint = ParserUtils.ParseDouble(tintAttr); // Or Convert.ToDouble with InvariantCulture
309 }
310 return Color.CreateTheme((Theme.ColorSchemeElement)themeIndex, tint);
311 }
312
313 // Check for system attribute (if supported)
314 string systemAttr = ReaderUtils.GetAttribute(colorNode, "system");
315 if (!string.IsNullOrEmpty(systemAttr))
316 {
317 SystemColor sysColor = new SystemColor(SystemColor.MapStringToValue(systemAttr));
318 return Color.CreateSystem(sysColor);
319 }
320
321 // No color defined
322 return Color.CreateNone();
323 }
324
329 private void GetFonts(XmlNode node)
330 {
331 string attribute;
332 foreach (XmlNode font in node.ChildNodes)
333 {
334 Font fontStyle = new Font();
335 XmlNode boldNode = ReaderUtils.GetChildNode(font, "b");
336 if (boldNode != null)
337 {
338 fontStyle.Bold = true;
339 }
340 XmlNode italicdNode = ReaderUtils.GetChildNode(font, "i");
341 if (italicdNode != null)
342 {
343 fontStyle.Italic = true;
344 }
345 XmlNode strikeNode = ReaderUtils.GetChildNode(font, "strike");
346 if (strikeNode != null)
347 {
348 fontStyle.Strike = true;
349 }
350 XmlNode outlineNode = ReaderUtils.GetChildNode(font, "outline");
351 if (outlineNode != null)
352 {
353 fontStyle.Outline = true;
354 }
355 XmlNode shadowNode = ReaderUtils.GetChildNode(font, "shadow");
356 if (shadowNode != null)
357 {
358 fontStyle.Shadow = true;
359 }
360 XmlNode condenseNode = ReaderUtils.GetChildNode(font, "condense");
361 if (condenseNode != null)
362 {
363 fontStyle.Condense = true;
364 }
365 XmlNode extendNode = ReaderUtils.GetChildNode(font, "extend");
366 if (extendNode != null)
367 {
368 fontStyle.Extend = true;
369 }
370 if (ReaderUtils.GetAttributeOfChild(font, "u", "val", out attribute))
371 {
372 if (attribute == null)
373 {
374 fontStyle.Underline = Font.UnderlineValue.Single; // Default value
375 }
376 else
377 {
378 fontStyle.Underline = Font.GetUnderlineEnum(attribute);
379 }
380 }
381 if (ReaderUtils.GetAttributeOfChild(font, "vertAlign", "val", out attribute))
382 {
383 fontStyle.VerticalAlign = Font.GetVerticalTextAlignEnum(attribute);
384 }
385 if (ReaderUtils.GetAttributeOfChild(font, "sz", "val", out attribute))
386 {
387 fontStyle.Size = ParserUtils.ParseFloat(attribute);
388 }
389 XmlNode colorNode = ReaderUtils.GetChildNode(font, "color");
390 if (colorNode != null)
391 {
392
393 attribute = ReaderUtils.GetAttribute(colorNode, "theme");
394 if (attribute != null)
395 {
396 ColorSchemeElement element = ColorSchemeElement.Dark1;
397 switch (attribute)
398 {
399 case "0":
400 element = ColorSchemeElement.Dark1;
401 break;
402 case "1":
403 element = ColorSchemeElement.Light1;
404 break;
405 case "2":
406 element = ColorSchemeElement.Dark2;
407 break;
408 case "3":
409 element = ColorSchemeElement.Light2;
410 break;
411 case "4":
412 element = ColorSchemeElement.Accent1;
413 break;
414 case "5":
415 element = ColorSchemeElement.Accent2;
416 break;
417 case "6":
418 element = ColorSchemeElement.Accent3;
419 break;
420 case "7":
421 element = ColorSchemeElement.Accent4;
422 break;
423 case "8":
424 element = ColorSchemeElement.Accent5;
425 break;
426 case "9":
427 element = ColorSchemeElement.Accent6;
428 break;
429 case "10":
430 element = ColorSchemeElement.Hyperlink;
431 break;
432 case "11":
433 element = ColorSchemeElement.FollowedHyperlink;
434 break;
435 }
436 fontStyle.ColorValue = Color.CreateTheme(element);
437
438 }
439 attribute = ReaderUtils.GetAttribute(colorNode, "rgb");
440 if (attribute != null)
441 {
442 fontStyle.ColorValue = Color.CreateRgb(attribute);
443 }
444 }
445 if (ReaderUtils.GetAttributeOfChild(font, "name", "val", out attribute))
446 {
447 fontStyle.Name = attribute;
448 }
449 if (ReaderUtils.GetAttributeOfChild(font, "family", "val", out attribute))
450 {
451 switch (attribute)
452 {
453
454 case "0":
455 fontStyle.Family = FontFamilyValue.NotApplicable;
456 break;
457 case "1":
458 fontStyle.Family = FontFamilyValue.Roman;
459 break;
460 case "2":
461 fontStyle.Family = FontFamilyValue.Swiss;
462 break;
463 case "3":
464 fontStyle.Family = FontFamilyValue.Modern;
465 break;
466 case "4":
467 fontStyle.Family = FontFamilyValue.Script;
468 break;
469 case "5":
470 fontStyle.Family = FontFamilyValue.Decorative;
471 break;
472 case "6":
473 fontStyle.Family = FontFamilyValue.Reserved1;
474 break;
475 case "7":
476 fontStyle.Family = FontFamilyValue.Reserved2;
477 break;
478 case "8":
479 fontStyle.Family = FontFamilyValue.Reserved3;
480 break;
481 case "9":
482 fontStyle.Family = FontFamilyValue.Reserved4;
483 break;
484 case "10":
485 fontStyle.Family = FontFamilyValue.Reserved5;
486 break;
487 case "11":
488 fontStyle.Family = FontFamilyValue.Reserved6;
489 break;
490 case "12":
491 fontStyle.Family = FontFamilyValue.Reserved7;
492 break;
493 case "13":
494 fontStyle.Family = FontFamilyValue.Reserved8;
495 break;
496 case "14":
497 fontStyle.Family = FontFamilyValue.Reserved9;
498 break;
499 }
500 }
501 if (ReaderUtils.GetAttributeOfChild(font, "scheme", "val", out attribute))
502 {
503 switch (attribute)
504 {
505 case "major":
506 fontStyle.Scheme = SchemeValue.Major;
507 break;
508 case "minor":
509 fontStyle.Scheme = SchemeValue.Minor;
510 break;
511 }
512 }
513 if (ReaderUtils.GetAttributeOfChild(font, "charset", "val", out attribute))
514 {
515 switch (attribute)
516 {
517 case "0":
518 fontStyle.Charset = CharsetValue.ANSI;
519 break;
520 case "1":
521 fontStyle.Charset = CharsetValue.Default;
522 break;
523 case "2":
524 fontStyle.Charset = CharsetValue.Symbols;
525 break;
526 case "77":
527 fontStyle.Charset = CharsetValue.Macintosh;
528 break;
529 case "128":
530 fontStyle.Charset = CharsetValue.JIS;
531 break;
532 case "129":
533 fontStyle.Charset = CharsetValue.Hangul;
534 break;
535 case "130":
536 fontStyle.Charset = CharsetValue.Johab;
537 break;
538 case "134":
539 fontStyle.Charset = CharsetValue.GBK;
540 break;
541 case "136":
542 fontStyle.Charset = CharsetValue.Big5;
543 break;
544 case "161":
545 fontStyle.Charset = CharsetValue.Greek;
546 break;
547 case "162":
548 fontStyle.Charset = CharsetValue.Turkish;
549 break;
550 case "163":
551 fontStyle.Charset = CharsetValue.Vietnamese;
552 break;
553 case "177":
554 fontStyle.Charset = CharsetValue.Hebrew;
555 break;
556 case "178":
557 fontStyle.Charset = CharsetValue.Arabic;
558 break;
559 case "186":
560 fontStyle.Charset = CharsetValue.Baltic;
561 break;
562 case "204":
563 fontStyle.Charset = CharsetValue.Russian;
564 break;
565 case "222":
566 fontStyle.Charset = CharsetValue.Thai;
567 break;
568 case "238":
569 fontStyle.Charset = CharsetValue.EasternEuropean;
570 break;
571 case "255":
572 fontStyle.Charset = CharsetValue.OEM;
573 break;
574 default:
575 fontStyle.Charset = CharsetValue.ApplicationDefined;
576 break;
577 }
578 }
579
580 fontStyle.InternalID = this.styleReaderContainer.GetNextFontId();
581 this.styleReaderContainer.AddStyleComponent(fontStyle);
582 }
583 }
584
589 private void GetCellXfs(XmlNode node)
590 {
591 foreach (XmlNode childNode in node.ChildNodes)
592 {
593 if (ReaderUtils.IsNode(childNode, "xf"))
594 {
595 CellXf cellXfStyle = new CellXf();
596 string attribute = ReaderUtils.GetAttribute(childNode, "applyAlignment");
597 if (attribute != null)
598 {
599 int value = ParserUtils.ParseBinaryBool(attribute);
600 cellXfStyle.ForceApplyAlignment = value == 1;
601 }
602 XmlNode alignmentNode = ReaderUtils.GetChildNode(childNode, "alignment");
603 if (alignmentNode != null)
604 {
605 attribute = ReaderUtils.GetAttribute(alignmentNode, "shrinkToFit");
606 if (attribute != null)
607 {
608 int value = ParserUtils.ParseBinaryBool(attribute);
609 if (value == 1)
610 {
611 cellXfStyle.Alignment = TextBreakValue.ShrinkToFit;
612 }
613 }
614 attribute = ReaderUtils.GetAttribute(alignmentNode, "wrapText");
615 if (attribute != null && attribute == "1")
616 {
617 cellXfStyle.Alignment = TextBreakValue.WrapText;
618 }
619 attribute = ReaderUtils.GetAttribute(alignmentNode, "horizontal", string.Empty);
620 cellXfStyle.HorizontalAlign = CellXf.GetHorizontalAlignEnum(attribute);
621 attribute = ReaderUtils.GetAttribute(alignmentNode, "vertical", string.Empty);
622 cellXfStyle.VerticalAlign = CellXf.GetVerticalAlignEnum(attribute);
623 attribute = ReaderUtils.GetAttribute(alignmentNode, "indent");
624 if (attribute != null)
625 {
626 cellXfStyle.Indent = ParserUtils.ParseInt(attribute);
627 }
628 attribute = ReaderUtils.GetAttribute(alignmentNode, "textRotation");
629 if (attribute != null)
630 {
631 int rotation = ParserUtils.ParseInt(attribute);
632 cellXfStyle.TextRotation = rotation > 90 ? 90 - rotation : rotation;
633 }
634 }
635 XmlNode protectionNode = ReaderUtils.GetChildNode(childNode, "protection");
636 if (protectionNode != null)
637 {
638 attribute = ReaderUtils.GetAttribute(protectionNode, "hidden");
639 if (attribute != null && attribute == "1")
640 {
641 cellXfStyle.Hidden = true;
642 }
643 attribute = ReaderUtils.GetAttribute(protectionNode, "locked");
644 if (attribute != null && attribute == "0")
645 {
646 cellXfStyle.Locked = false;
647 }
648 // else - NoOp - No need to set locked value, since true by default
649 }
650
651 cellXfStyle.InternalID = this.styleReaderContainer.GetNextCellXFId();
652 this.styleReaderContainer.AddStyleComponent(cellXfStyle);
653
654 Style style = new Style();
655 int id;
656 bool hasId;
657
658 hasId = ParserUtils.TryParseInt(ReaderUtils.GetAttribute(childNode, "numFmtId"), out id);
659 NumberFormat format = this.styleReaderContainer.GetNumberFormat(id);
660 if (!hasId || format == null)
661 {
662 FormatNumber formatNumber;
663 NumberFormat.TryParseFormatNumber(id, out formatNumber); // Validity is neglected here to prevent unhandled crashes. If invalid, the format will be declared as 'none'.
664 // Invalid values should not occur at all (malformed Excel files).
665 // Undefined values may occur if the file was saved by an Excel version that has implemented yet unknown format numbers (undefined in NanoXLSX)
666 format = new NumberFormat
667 {
668 Number = formatNumber,
669 InternalID = id
670 };
671 this.styleReaderContainer.AddStyleComponent(format);
672 }
673 hasId = ParserUtils.TryParseInt(ReaderUtils.GetAttribute(childNode, "borderId"), out id);
674 Border border = this.styleReaderContainer.GetBorder(id);
675 if (!hasId || border == null)
676 {
677 border = new Border
678 {
679 InternalID = this.styleReaderContainer.GetNextBorderId()
680 };
681 }
682 hasId = ParserUtils.TryParseInt(ReaderUtils.GetAttribute(childNode, "fillId"), out id);
683 Fill fill = this.styleReaderContainer.GetFill(id);
684 if (!hasId || fill == null)
685 {
686 fill = new Fill
687 {
688 InternalID = this.styleReaderContainer.GetNextFillId()
689 };
690 }
691 hasId = ParserUtils.TryParseInt(ReaderUtils.GetAttribute(childNode, "fontId"), out id);
692 Font font = this.styleReaderContainer.GetFont(id);
693 if (!hasId || font == null)
694 {
695 font = new Font
696 {
697 InternalID = this.styleReaderContainer.GetNextFontId()
698 };
699 }
700
701 // TODO: Implement other style information
702 style.CurrentNumberFormat = format;
703 style.CurrentBorder = border;
704 style.CurrentFill = fill;
705 style.CurrentFont = font;
706 style.CurrentCellXf = cellXfStyle;
707 style.InternalID = this.styleReaderContainer.GetNextStyleId();
708
709 this.styleReaderContainer.AddStyleComponent(style);
710 }
711 }
712 }
713
718 private void GetColors(XmlNode node)
719 {
720 foreach (XmlNode color in node.ChildNodes)
721 {
722 XmlNode mruColor = ReaderUtils.GetChildNode(color, "color");
723 if (color.Name.Equals("mruColors", StringComparison.Ordinal) && mruColor != null)
724 {
725 foreach (XmlNode value in color.ChildNodes)
726 {
727 string attribute = ReaderUtils.GetAttribute(value, "rgb");
728 if (attribute != null)
729 {
730 this.styleReaderContainer.AddMruColor(attribute);
731 }
732 }
733 }
734 }
735 }
736
743 private static string GetColor(XmlNode node, string fallback)
744 {
745 XmlNode childNode = ReaderUtils.GetChildNode(node, "color");
746 if (childNode != null)
747 {
748 string color = ReaderUtils.GetAttribute(childNode, "rgb");
749 if (color != null)
750 {
751 return color;
752 }
753 }
754 return fallback;
755 }
756 #endregion
757 }
758}
StyleReader()
Initializes a new instance of the StyleReader class.
Workbook Workbook
Workbook reference where read data is stored (should not be null).
void Execute()
Method to execute the main logic of the plug-in (interface implementation).
void Init(MemoryStream stream, Workbook workbook, IOptions readerOptions)
Default constructor - Must be defined for instantiation of the plug-ins.
Class representing a collection of pre-processed styles and their components. This class is internall...
void AddStyleComponent(AbstractStyle component)
Adds a style component and determines the appropriate type of it automatically.
Exceptions.IOException IOException