37 private Stream stream;
73 public void Init(Stream stream,
Workbook workbook, IOptions readerOptions, Action<Stream, Workbook, string, IOptions, int?> inlinePluginHandler)
76 this.Workbook = workbook;
77 this.Options = readerOptions;
78 this.InlinePluginHandler = inlinePluginHandler;
92 using (XmlReader reader = XmlReader.Create(stream, XmlStreamUtils.CreateSettings()))
96 if (reader.NodeType != XmlNodeType.Element)
100 switch (reader.LocalName.ToLowerInvariant())
103 GetNumberFormats(reader);
126 Workbook.AuxiliaryData.SetData(PlugInUUID.StyleReader, PlugInUUID.StyleEntity, styleReaderContainer);
130 throw new IOException(
"The XML entry could not be read from the input stream. Please see the inner exception:", ex);
137 private void HandleMruColors()
139 List<string> mruColors = styleReaderContainer.GetMruColors();
140 foreach (
string color
in mruColors)
150 private void GetNumberFormats(XmlReader reader)
152 using (XmlReader subtree = reader.ReadSubtree())
155 while (subtree.Read())
157 if (!XmlStreamUtils.IsElement(subtree,
"numFmt"))
161 NumberFormat numberFormat =
new NumberFormat();
162 int id = ParserUtils.ParseInt(subtree.GetAttribute(
"numFmtId"));
163 string code = subtree.GetAttribute(
"formatCode") ??
string.Empty;
164 numberFormat.CustomFormatID = id;
165 numberFormat.Number = FormatNumber.Custom;
166 numberFormat.InternalID = id;
167 numberFormat.CustomFormatCode = code;
177 private void GetBorders(XmlReader reader)
179 using (XmlReader subtree = reader.ReadSubtree())
182 while (subtree.Read())
184 if (!XmlStreamUtils.IsElement(subtree,
"border"))
188 Border borderStyle =
new Border();
189 string diagonalDown = subtree.GetAttribute(
"diagonalDown");
190 if (diagonalDown !=
null && ParserUtils.ParseBinaryBool(diagonalDown) == 1)
192 borderStyle.DiagonalDown =
true;
194 string diagonalUp = subtree.GetAttribute(
"diagonalUp");
195 if (diagonalUp !=
null && ParserUtils.ParseBinaryBool(diagonalUp) == 1)
197 borderStyle.DiagonalUp =
true;
199 StyleValue sideStyle;
201 using (XmlReader borderSubtree = subtree.ReadSubtree())
203 borderSubtree.Read();
204 while (borderSubtree.Read())
206 if (borderSubtree.NodeType != XmlNodeType.Element)
210 switch (borderSubtree.LocalName.ToLowerInvariant())
213 ReadBorderSide(borderSubtree, out sideStyle, out sideColor);
214 borderStyle.DiagonalStyle = sideStyle;
215 borderStyle.DiagonalColor = sideColor;
218 ReadBorderSide(borderSubtree, out sideStyle, out sideColor);
219 borderStyle.TopStyle = sideStyle;
220 borderStyle.TopColor = sideColor;
223 ReadBorderSide(borderSubtree, out sideStyle, out sideColor);
224 borderStyle.BottomStyle = sideStyle;
225 borderStyle.BottomColor = sideColor;
228 ReadBorderSide(borderSubtree, out sideStyle, out sideColor);
229 borderStyle.LeftStyle = sideStyle;
230 borderStyle.LeftColor = sideColor;
233 ReadBorderSide(borderSubtree, out sideStyle, out sideColor);
234 borderStyle.RightStyle = sideStyle;
235 borderStyle.RightColor = sideColor;
240 borderStyle.InternalID = this.styleReaderContainer.GetNextBorderId();
241 this.styleReaderContainer.AddStyleComponent(borderStyle);
250 private static void ReadBorderSide(XmlReader reader, out StyleValue style, out
string color)
252 style = StyleValue.None;
253 color = Border.DefaultBorderColor;
254 string styleAttr = reader.GetAttribute(
"style");
255 if (styleAttr !=
null)
257 style = Border.GetStyleEnum(styleAttr);
259 if (reader.IsEmptyElement)
263 using (XmlReader subtree = reader.ReadSubtree())
266 while (subtree.Read())
268 if (subtree.NodeType == XmlNodeType.Element
269 && subtree.LocalName.Equals(
"color", StringComparison.OrdinalIgnoreCase))
271 string rgb = subtree.GetAttribute(
"rgb");
286 private void GetFills(XmlReader reader)
288 using (XmlReader subtree = reader.ReadSubtree())
291 while (subtree.Read())
293 if (!XmlStreamUtils.IsElement(subtree,
"fill"))
297 Fill fillStyle =
new Fill();
298 using (XmlReader fillSubtree = subtree.ReadSubtree())
301 while (fillSubtree.Read())
303 if (!XmlStreamUtils.IsElement(fillSubtree,
"patternFill"))
307 fillStyle.PatternFill = Fill.GetPatternEnum(fillSubtree.GetAttribute(
"patternType") ??
string.Empty);
308 using (XmlReader patternSubtree = fillSubtree.ReadSubtree())
310 patternSubtree.Read();
311 while (patternSubtree.Read())
313 if (patternSubtree.NodeType != XmlNodeType.Element)
317 if (patternSubtree.LocalName.Equals(
"fgColor", StringComparison.OrdinalIgnoreCase))
319 fillStyle.ForegroundColor = ReadColorFromNode(patternSubtree);
321 else if (patternSubtree.LocalName.Equals(
"bgColor", StringComparison.OrdinalIgnoreCase))
323 fillStyle.BackgroundColor = ReadColorFromNode(patternSubtree);
329 fillStyle.InternalID = this.styleReaderContainer.GetNextFillId();
330 this.styleReaderContainer.AddStyleComponent(fillStyle);
338 private static Color ReadColorFromNode(XmlReader reader)
340 string autoAttr = reader.GetAttribute(
"auto");
341 if (!
string.IsNullOrEmpty(autoAttr) && ParserUtils.ParseBinaryBool(autoAttr) == 1)
343 return Color.CreateAuto();
345 string rgbAttr = reader.GetAttribute(
"rgb");
346 if (!
string.IsNullOrEmpty(rgbAttr))
348 return Color.CreateRgb(rgbAttr);
350 string indexedAttr = reader.GetAttribute(
"indexed");
351 if (!
string.IsNullOrEmpty(indexedAttr))
353 return Color.CreateIndexed(ParserUtils.ParseInt(indexedAttr));
355 string themeAttr = reader.GetAttribute(
"theme");
356 if (!
string.IsNullOrEmpty(themeAttr))
358 int themeIndex = ParserUtils.ParseInt(themeAttr);
359 string tintAttr = reader.GetAttribute(
"tint");
361 if (!
string.IsNullOrEmpty(tintAttr))
363 tint = ParserUtils.ParseDouble(tintAttr);
365 return Color.CreateTheme((Theme.ColorSchemeElement)themeIndex, tint);
367 string systemAttr = reader.GetAttribute(
"system");
368 if (!
string.IsNullOrEmpty(systemAttr))
370 return Color.CreateSystem(
new SystemColor(SystemColor.MapStringToValue(systemAttr)));
372 return Color.CreateNone();
379 private void GetFonts(XmlReader reader)
381 using (XmlReader subtree = reader.ReadSubtree())
384 while (subtree.Read())
386 if (!XmlStreamUtils.IsElement(subtree,
"font"))
390 Font fontStyle =
new Font();
391 ReadFontElement(subtree, fontStyle);
392 fontStyle.InternalID = this.styleReaderContainer.GetNextFontId();
393 this.styleReaderContainer.AddStyleComponent(fontStyle);
401 private static void ReadFontElement(XmlReader reader, Font fontStyle)
403 using (XmlReader fontSubtree = reader.ReadSubtree())
406 while (fontSubtree.Read())
408 if (fontSubtree.NodeType != XmlNodeType.Element)
413 switch (fontSubtree.LocalName.ToLowerInvariant())
416 fontStyle.Bold =
true;
419 fontStyle.Italic =
true;
422 fontStyle.Strike =
true;
425 fontStyle.Outline =
true;
428 fontStyle.Shadow =
true;
431 fontStyle.Condense =
true;
434 fontStyle.Extend =
true;
437 val = fontSubtree.GetAttribute(
"val");
438 fontStyle.Underline = val ==
null ? Font.UnderlineValue.Single : Font.GetUnderlineEnum(val);
441 fontStyle.VerticalAlign = Font.GetVerticalTextAlignEnum(fontSubtree.GetAttribute(
"val"));
444 fontStyle.Size = ParserUtils.ParseFloat(fontSubtree.GetAttribute(
"val"));
447 string themeVal = fontSubtree.GetAttribute(
"theme");
448 if (themeVal !=
null)
450 fontStyle.ColorValue = Color.CreateTheme(ParseFontColorSchemeElement(themeVal));
452 string rgbVal = fontSubtree.GetAttribute(
"rgb");
455 fontStyle.ColorValue = Color.CreateRgb(rgbVal);
459 fontStyle.Name = fontSubtree.GetAttribute(
"val");
462 val = fontSubtree.GetAttribute(
"val");
465 fontStyle.Family = ParseFontFamilyValue(val);
469 val = fontSubtree.GetAttribute(
"val");
475 fontStyle.Scheme = SchemeValue.Major;
478 fontStyle.Scheme = SchemeValue.Minor;
484 val = fontSubtree.GetAttribute(
"val");
487 fontStyle.Charset = ParseFontCharsetValue(val);
498 private static ColorSchemeElement ParseFontColorSchemeElement(
string value)
502 case "1":
return ColorSchemeElement.Light1;
503 case "2":
return ColorSchemeElement.Dark2;
504 case "3":
return ColorSchemeElement.Light2;
505 case "4":
return ColorSchemeElement.Accent1;
506 case "5":
return ColorSchemeElement.Accent2;
507 case "6":
return ColorSchemeElement.Accent3;
508 case "7":
return ColorSchemeElement.Accent4;
509 case "8":
return ColorSchemeElement.Accent5;
510 case "9":
return ColorSchemeElement.Accent6;
511 case "10":
return ColorSchemeElement.Hyperlink;
512 case "11":
return ColorSchemeElement.FollowedHyperlink;
513 default:
return ColorSchemeElement.Dark1;
520 private static FontFamilyValue ParseFontFamilyValue(
string value)
524 case "1":
return FontFamilyValue.Roman;
525 case "2":
return FontFamilyValue.Swiss;
526 case "3":
return FontFamilyValue.Modern;
527 case "4":
return FontFamilyValue.Script;
528 case "5":
return FontFamilyValue.Decorative;
529 case "6":
return FontFamilyValue.Reserved1;
530 case "7":
return FontFamilyValue.Reserved2;
531 case "8":
return FontFamilyValue.Reserved3;
532 case "9":
return FontFamilyValue.Reserved4;
533 case "10":
return FontFamilyValue.Reserved5;
534 case "11":
return FontFamilyValue.Reserved6;
535 case "12":
return FontFamilyValue.Reserved7;
536 case "13":
return FontFamilyValue.Reserved8;
537 case "14":
return FontFamilyValue.Reserved9;
538 default:
return FontFamilyValue.NotApplicable;
545 private static CharsetValue ParseFontCharsetValue(
string value)
549 case "0":
return CharsetValue.ANSI;
550 case "1":
return CharsetValue.Default;
551 case "2":
return CharsetValue.Symbols;
552 case "77":
return CharsetValue.Macintosh;
553 case "128":
return CharsetValue.JIS;
554 case "129":
return CharsetValue.Hangul;
555 case "130":
return CharsetValue.Johab;
556 case "134":
return CharsetValue.GBK;
557 case "136":
return CharsetValue.Big5;
558 case "161":
return CharsetValue.Greek;
559 case "162":
return CharsetValue.Turkish;
560 case "163":
return CharsetValue.Vietnamese;
561 case "177":
return CharsetValue.Hebrew;
562 case "178":
return CharsetValue.Arabic;
563 case "186":
return CharsetValue.Baltic;
564 case "204":
return CharsetValue.Russian;
565 case "222":
return CharsetValue.Thai;
566 case "238":
return CharsetValue.EasternEuropean;
567 case "255":
return CharsetValue.OEM;
568 default:
return CharsetValue.ApplicationDefined;
577 private void GetCellXfs(XmlReader reader)
579 using (XmlReader subtree = reader.ReadSubtree())
582 while (subtree.Read())
584 if (!XmlStreamUtils.IsElement(subtree,
"xf"))
588 CellXf cellXfStyle =
new CellXf();
589 string applyAlignment = subtree.GetAttribute(
"applyAlignment");
590 if (applyAlignment !=
null)
592 cellXfStyle.ForceApplyAlignment = ParserUtils.ParseBinaryBool(applyAlignment) == 1;
594 string numFmtIdStr = subtree.GetAttribute(
"numFmtId");
595 string borderIdStr = subtree.GetAttribute(
"borderId");
596 string fillIdStr = subtree.GetAttribute(
"fillId");
597 string fontIdStr = subtree.GetAttribute(
"fontId");
598 if (!subtree.IsEmptyElement)
600 using (XmlReader xfSubtree = subtree.ReadSubtree())
603 while (xfSubtree.Read())
605 if (xfSubtree.NodeType != XmlNodeType.Element)
609 if (xfSubtree.LocalName.Equals(
"alignment", StringComparison.OrdinalIgnoreCase))
611 ReadXfAlignment(xfSubtree, cellXfStyle);
613 else if (xfSubtree.LocalName.Equals(
"protection", StringComparison.OrdinalIgnoreCase))
615 ReadXfProtection(xfSubtree, cellXfStyle);
620 cellXfStyle.InternalID = this.styleReaderContainer.GetNextCellXFId();
621 this.styleReaderContainer.AddStyleComponent(cellXfStyle);
623 Style style =
new Style();
627 hasId = ParserUtils.TryParseInt(numFmtIdStr, out
id);
628 NumberFormat format = this.styleReaderContainer.GetNumberFormat(
id);
629 if (!hasId || format ==
null)
631 FormatNumber formatNumber;
632 NumberFormat.TryParseFormatNumber(
id, out formatNumber);
633 format =
new NumberFormat
635 Number = formatNumber,
638 this.styleReaderContainer.AddStyleComponent(format);
640 hasId = ParserUtils.TryParseInt(borderIdStr, out
id);
641 Border border = this.styleReaderContainer.GetBorder(
id);
642 if (!hasId || border ==
null)
646 InternalID = this.styleReaderContainer.GetNextBorderId()
649 hasId = ParserUtils.TryParseInt(fillIdStr, out
id);
650 Fill fill = this.styleReaderContainer.GetFill(
id);
651 if (!hasId || fill ==
null)
655 InternalID = this.styleReaderContainer.GetNextFillId()
658 hasId = ParserUtils.TryParseInt(fontIdStr, out
id);
659 Font font = this.styleReaderContainer.GetFont(
id);
660 if (!hasId || font ==
null)
664 InternalID = this.styleReaderContainer.GetNextFontId()
667 style.CurrentNumberFormat = format;
668 style.CurrentBorder = border;
669 style.CurrentFill = fill;
670 style.CurrentFont = font;
671 style.CurrentCellXf = cellXfStyle;
672 style.InternalID = this.styleReaderContainer.GetNextStyleId();
673 this.styleReaderContainer.AddStyleComponent(style);
681 private static void ReadXfAlignment(XmlReader reader, CellXf cellXfStyle)
683 string shrinkToFit = reader.GetAttribute(
"shrinkToFit");
684 if (shrinkToFit !=
null && ParserUtils.ParseBinaryBool(shrinkToFit) == 1)
686 cellXfStyle.Alignment = TextBreakValue.ShrinkToFit;
688 string wrapText = reader.GetAttribute(
"wrapText");
689 if (wrapText !=
null && wrapText ==
"1")
691 cellXfStyle.Alignment = TextBreakValue.WrapText;
693 cellXfStyle.HorizontalAlign = CellXf.GetHorizontalAlignEnum(reader.GetAttribute(
"horizontal") ??
string.Empty);
694 cellXfStyle.VerticalAlign = CellXf.GetVerticalAlignEnum(reader.GetAttribute(
"vertical") ??
string.Empty);
695 string indent = reader.GetAttribute(
"indent");
698 cellXfStyle.Indent = ParserUtils.ParseInt(indent);
700 string textRotation = reader.GetAttribute(
"textRotation");
701 if (textRotation !=
null)
703 int rotation = ParserUtils.ParseInt(textRotation);
704 cellXfStyle.TextRotation = rotation > 90 ? 90 - rotation : rotation;
711 private static void ReadXfProtection(XmlReader reader, CellXf cellXfStyle)
713 string hidden = reader.GetAttribute(
"hidden");
714 if (hidden !=
null && hidden ==
"1")
716 cellXfStyle.Hidden =
true;
718 string locked = reader.GetAttribute(
"locked");
719 if (locked !=
null && locked ==
"0")
721 cellXfStyle.Locked =
false;
729 private void GetColors(XmlReader reader)
731 using (XmlReader subtree = reader.ReadSubtree())
734 while (subtree.Read())
736 if (subtree.NodeType == XmlNodeType.Element
737 && subtree.LocalName.Equals(
"mruColors", StringComparison.OrdinalIgnoreCase))
739 ReadMruColors(subtree);
748 private void ReadMruColors(XmlReader reader)
750 using (XmlReader subtree = reader.ReadSubtree())
753 while (subtree.Read())
755 if (subtree.NodeType == XmlNodeType.Element
756 && subtree.LocalName.Equals(
"color", StringComparison.OrdinalIgnoreCase))
758 string rgb = subtree.GetAttribute(
"rgb");
761 this.styleReaderContainer.AddMruColor(rgb);