8using NanoXLSX.Interfaces;
9using NanoXLSX.Interfaces.Writer;
10using NanoXLSX.Registry;
11using NanoXLSX.Registry.Attributes;
14using NanoXLSX.Utils.Xml;
22 [NanoXlsxPlugIn(PlugInUUID = PlugInUUID.WorkbookWriter)]
23 internal class WorkbookWriter : IPluginWriter
25 private XmlElement workbook;
26 private IPasswordWriter passwordWriter;
32 public Workbook Workbook {
get;
set; }
37 public XmlElement XmlElement => workbook;
44 internal WorkbookWriter()
54 public void Init(IBaseWriter baseWriter)
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);
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)
74 workbookPr.AddAttribute(
"defaultThemeVersion", Theme.DefaultThemeVersion);
77 if (wb.SelectedWorksheet > 0 || wb.Hidden || HasPaneSplitting())
79 XmlElement bookViews = workbook.AddChildElement(
"bookViews");
80 XmlElement workbookView = bookViews.AddChildElement(
"workbookView");
83 workbookView.AddAttribute(
"visibility",
"hidden");
87 workbookView.AddAttribute(
"activeTab", ParserUtils.ToString(wb.SelectedWorksheet));
90 workbook.AddChildElement(GetWorkbookProtectionElement());
91 XmlElement sheets = workbook.AddChildElement(
"sheets");
92 if (wb.Worksheets.Count > 0)
94 foreach (Worksheet item
in wb.Worksheets)
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));
101 sheet.AddAttribute(
"state",
"hidden");
108 XmlElement sheet = sheets.AddChildElementWithAttribute(
"sheet",
"id",
"rId1",
"",
"r");
109 sheet.AddAttribute(
"sheetId",
"1");
110 sheet.AddAttribute(
"name",
"sheet1");
112 workbook.AddChildElement(GetDefinedNamesElement());
114 WriterPlugInHandler.HandleInlineQueuePlugins(ref workbook, Workbook, PlugInUUID.WorkbookInlineWriter);
121 private XmlElement GetDefinedNamesElement()
123 System.Collections.Generic.IReadOnlyList<DefinedName> names = Workbook.GetDefinedNames();
124 if (names.Count == 0)
128 XmlElement definedNames = XmlElement.CreateElement(
"definedNames");
129 foreach (DefinedName item
in names)
131 XmlElement definedName = definedNames.AddChildElementWithValue(
"definedName", XmlUtils.SanitizeXmlValue(GetDefinedNameText(item)));
132 definedName.AddAttribute(
"name", XmlUtils.SanitizeXmlValue(item.Name));
133 if (item.LocalSheet !=
null)
135 int index = Workbook.Worksheets.IndexOf(item.LocalSheet);
138 definedName.AddAttribute(
"localSheetId", ParserUtils.ToString(index));
141 if (!
string.IsNullOrEmpty(item.Comment))
143 definedName.AddAttribute(
"comment", XmlUtils.SanitizeXmlValue(item.Comment));
149 private static string GetDefinedNameText(DefinedName definedName)
151 if ((definedName.Type == DefinedName.NameType.Cell || definedName.Type == DefinedName.NameType.Range)
152 && definedName.TargetWorksheet !=
null)
154 string worksheetName = definedName.TargetWorksheet.SheetName.Replace(
"'",
"''");
155 return "'" + worksheetName +
"'!" + definedName.TextValue;
157 if (definedName.Type == DefinedName.NameType.Constant && definedName.Value is
string stringValue)
159 return "\"" + stringValue.Replace(
"\"",
"\"\"") +
"\"";
161 return definedName.TextValue;
168 private XmlElement GetWorkbookProtectionElement()
170 Workbook workbook = Workbook;
171 XmlElement workbookProtection =
null;
172 if (workbook.UseWorkbookProtection)
174 workbookProtection = XmlElement.CreateElement(
"workbookProtection");
175 if (workbook.LockWindowsIfProtected)
177 workbookProtection.AddAttribute(
"lockWindows",
"1");
179 if (workbook.LockStructureIfProtected)
181 workbookProtection.AddAttribute(
"lockStructure",
"1");
183 if (passwordWriter.PasswordIsSet())
185 workbookProtection.AddAttributes(passwordWriter.GetAttributes());
188 return workbookProtection;
195 private bool HasPaneSplitting()
197 foreach (Worksheet worksheet
in Workbook.Worksheets)
199 if (worksheet.PaneSplitLeftWidth !=
null || worksheet.PaneSplitTopHeight !=
null || worksheet.PaneSplitAddress !=
null)