NanoXLSX.Writer 3.0.0-rc.3
Loading...
Searching...
No Matches
WorkbookWriter.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
10using NanoXLSX.Registry;
11using NanoXLSX.Registry.Attributes;
12using NanoXLSX.Themes;
13using NanoXLSX.Utils;
14using NanoXLSX.Utils.Xml;
16
18{
22 [NanoXlsxPlugIn(PlugInUUID = PlugInUUID.WorkbookWriter)]
23 internal class WorkbookWriter : IPlugInWriter
24 {
25 private XmlElement workbook;
26 private IPasswordWriter passwordWriter;
27
28 #region properties
32 public Workbook Workbook { get; set; }
33
37 public XmlElement XmlElement { get => workbook; }
38
39 #endregion
40 #region constructors
44 internal WorkbookWriter()
45 {
46 }
47
48 #endregion
49 #region methods
54 public void Init(IBaseWriter baseWriter)
55 {
56 this.Workbook = baseWriter.Workbook;
57 IPassword passwordInstance = Workbook.WorkbookProtectionPassword;
58 this.passwordWriter = PlugInLoader.GetPlugIn<IPasswordWriter>(PlugInUUID.PasswordWriter, new LegacyPasswordWriter());
59 this.passwordWriter.Init(PasswordType.WorkbookProtection, passwordInstance.PasswordHash);
60 }
61
65 public void Execute()
66 {
67 Workbook wb = Workbook;
68 workbook = XmlElement.CreateElement("workbook");
69 workbook.AddDefaultXmlNameSpace("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
70 workbook.AddNameSpaceAttribute("r", "xmlns", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
71 XmlElement workbookPr = workbook.AddChildElement("workbookPr");
72 if (wb.WorkbookTheme != null)
73 {
74 workbookPr.AddAttribute("defaultThemeVersion", Theme.DefaultThemeVersion);
75 // TODO: add further workbook properties here
76 }
77 if (wb.SelectedWorksheet > 0 || wb.Hidden || HasPaneSplitting())
78 {
79 XmlElement bookViews = workbook.AddChildElement("bookViews");
80 XmlElement workbookView = bookViews.AddChildElement("workbookView");
81 if (wb.Hidden)
82 {
83 workbookView.AddAttribute("visibility", "hidden");
84 }
85 else
86 {
87 workbookView.AddAttribute("activeTab", ParserUtils.ToString(wb.SelectedWorksheet));
88 }
89 }
90 workbook.AddChildElement(GetWorkbookProtectionElement());
91 XmlElement sheets = workbook.AddChildElement("sheets");
92 if (wb.Worksheets.Count > 0)
93 {
94 foreach (Worksheet item in wb.Worksheets)
95 {
96 XmlElement sheet = sheets.AddChildElementWithAttribute("sheet", "id", "rId" + ParserUtils.ToString(item.SheetID), "", "r");
97 sheet.AddAttribute("sheetId", item.SheetID.ToString());
98 sheet.AddAttribute("name", XmlUtils.SanitizeXmlValue(item.SheetName));
99 if (item.Hidden)
100 {
101 sheet.AddAttribute("state", "hidden");
102 }
103 }
104 }
105 else
106 {
107 // Fallback on empty workbook
108 XmlElement sheet = sheets.AddChildElementWithAttribute("sheet", "id", "rId1", "", "r");
109 sheet.AddAttribute("sheetId", "1");
110 sheet.AddAttribute("name", "sheet1");
111 }
112
113 WriterPlugInHandler.HandleInlineQueuePlugins(ref workbook, Workbook, PlugInUUID.WorkbookInlineWriter);
114 }
115
120 private XmlElement GetWorkbookProtectionElement()
121 {
122 Workbook workbook = Workbook;
123 XmlElement workbookProtection = null;
124 if (workbook.UseWorkbookProtection)
125 {
126 workbookProtection = XmlElement.CreateElement("workbookProtection");
127 if (workbook.LockWindowsIfProtected)
128 {
129 workbookProtection.AddAttribute("lockWindows", "1");
130 }
131 if (workbook.LockStructureIfProtected)
132 {
133 workbookProtection.AddAttribute("lockStructure", "1");
134 }
135 if (passwordWriter.PasswordIsSet())
136 {
137 workbookProtection.AddAttributes(passwordWriter.GetAttributes());
138 }
139 }
140 return workbookProtection;
141 }
142
147 private bool HasPaneSplitting()
148 {
149 foreach (Worksheet worksheet in Workbook.Worksheets)
150 {
151 if (worksheet.PaneSplitLeftWidth != null || worksheet.PaneSplitTopHeight != null || worksheet.PaneSplitAddress != null)
152 {
153 return true;
154 }
155 }
156 return false;
157 }
158
159 #endregion
160
161 }
162}
Static class that contains enums for password handling.