NanoXLSX.Reader 3.0.0-rc.3
Loading...
Searching...
No Matches
ThemeReader.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.IO;
10using System.Xml;
11using NanoXLSX.Colors;
13using NanoXLSX.Interfaces.Plugin;
15using NanoXLSX.Registry;
16using NanoXLSX.Registry.Attributes;
17using NanoXLSX.Themes;
18using IOException = NanoXLSX.Exceptions.IOException;
19
21{
25 [NanoXlsxPlugIn(PlugInUUID = PlugInUUID.ThemeReader)]
26 public class ThemeReader : IPluginReader
27 {
28
29 private MemoryStream stream;
30
31 #region properties
35 public Workbook Workbook { get; set; }
36 #endregion
37
38 #region constructors
42 internal ThemeReader()
43 {
44 }
45 #endregion
46
47 #region methods
54 public void Init(MemoryStream stream, Workbook workbook, IOptions readerOptions)
55 {
56 this.stream = stream;
57 this.Workbook = workbook;
58 }
59
64 public void Execute()
65 {
66 try
67 {
68 using (stream) // Close after processing
69 {
70 XmlDocument xr = new XmlDocument() { XmlResolver = null };
71 using (XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { XmlResolver = null }))
72 {
73 xr.Load(reader);
74 string prefix = ReaderUtils.DiscoverPrefix(xr, "theme");
75 XmlNodeList themes = ReaderUtils.GetElementsByTagName(xr, "theme", prefix);
76 string themeName = ReaderUtils.GetAttribute(themes[0], "name"); // If this fails, something is completely wrong
77 Workbook.WorkbookTheme = new Theme(themeName);
78 ColorScheme colorScheme = new ColorScheme();
79 Workbook.WorkbookTheme.Colors = colorScheme;
80 XmlNodeList colors = ReaderUtils.GetElementsByTagName(xr, "clrScheme", prefix);
81
82 foreach (XmlNode color in colors)
83 {
84 string colorSchemeName = ReaderUtils.GetAttribute(color, "name", "");
85 Workbook.WorkbookTheme.Colors.Name = colorSchemeName;
86 XmlNodeList colorNodes = color.ChildNodes;
87 foreach (XmlNode colorNode in colorNodes)
88 {
89 string name = colorNode.LocalName;
90 switch (name)
91 {
92 case "dk1":
93 colorScheme.Dark1 = ParseColor(colorNode.ChildNodes);
94 break;
95 case "lt1":
96 colorScheme.Light1 = ParseColor(colorNode.ChildNodes);
97 break;
98 case "dk2":
99 colorScheme.Dark2 = ParseColor(colorNode.ChildNodes);
100 break;
101 case "lt2":
102 colorScheme.Light2 = ParseColor(colorNode.ChildNodes);
103 break;
104 case "accent1":
105 colorScheme.Accent1 = ParseColor(colorNode.ChildNodes);
106 break;
107 case "accent2":
108 colorScheme.Accent2 = ParseColor(colorNode.ChildNodes);
109 break;
110 case "accent3":
111 colorScheme.Accent3 = ParseColor(colorNode.ChildNodes);
112 break;
113 case "accent4":
114 colorScheme.Accent4 = ParseColor(colorNode.ChildNodes);
115 break;
116 case "accent5":
117 colorScheme.Accent5 = ParseColor(colorNode.ChildNodes);
118 break;
119 case "accent6":
120 colorScheme.Accent6 = ParseColor(colorNode.ChildNodes);
121 break;
122 case "hlink":
123 colorScheme.Hyperlink = ParseColor(colorNode.ChildNodes);
124 break;
125 case "folHlink":
126 colorScheme.FollowedHyperlink = ParseColor(colorNode.ChildNodes);
127 break;
128 }
129
130 }
131 }
132 RederPlugInHandler.HandleInlineQueuePlugins(ref stream, Workbook, PlugInUUID.ThemeInlineReader);
133 }
134 }
135 }
136 catch (Exception ex)
137 {
138 throw new IOException("The XML entry could not be read from the input stream. Please see the inner exception:", ex);
139 }
140 }
141
147 private static IColor ParseColor(XmlNodeList childNodes)
148 {
149 foreach (XmlNode node in childNodes)
150 {
151 if (node.LocalName == "sysClr")
152 {
153 SystemColor.Value value = ParseSystemColor(node);
154 SystemColor systemColor = new SystemColor
155 {
156 ColorValue = value
157 };
158 string lastColor = ReaderUtils.GetAttribute(node, "lastClr");
159 if (lastColor != null)
160 {
161 systemColor.LastColor = lastColor;
162 }
163 return systemColor;
164 }
165 else if (node.LocalName == "srgbClr")
166 {
167 SrgbColor srgbColor = new SrgbColor
168 {
169 ColorValue = ReaderUtils.GetAttribute(node, "val")
170 };
171 return srgbColor;
172 }
173 }
174 return null;
175 }
176
183 private static SystemColor.Value ParseSystemColor(XmlNode innerNode)
184 {
185 string value = ReaderUtils.GetAttribute(innerNode, "val");
186 if (string.IsNullOrEmpty(value))
187 {
188 throw new IOException("The system color entry was null or empty");
189 }
190 try
191 {
192 return SystemColor.MapStringToValue(value);
193 }
194 catch (Exception ex)
195 {
196 throw new IOException("The system color entry '" + value + "' could not be parsed", ex);
197 }
198 }
199 #endregion
200 }
201}
Static class with common util methods, used during reading XLSX files.
static string GetAttribute(XmlNode node, string targetName, string fallbackValue=null)
Gets the XML attribute of the passed XML node by its name.
Class representing a reader for theme definitions of XLSX files.
void Execute()
Method to execute the main logic of the plug-in (interface implementation).
Workbook Workbook
Workbook reference where read data is stored (should not be null).
void Init(MemoryStream stream, Workbook workbook, IOptions readerOptions)
Initialization method (interface implementation).
Exceptions.IOException IOException