NanoXLSX.Core 3.0.0-rc.3
Loading...
Searching...
No Matches
Workbook.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.Collections.Generic;
9using System.Linq;
13using NanoXLSX.Themes;
14using NanoXLSX.Utils;
15
16namespace NanoXLSX
17{
22 public class Workbook
23 {
24 static Workbook()
25 {
27 }
28
29 #region privateFields
30 private string filename;
31 private List<Worksheet> worksheets;
32 private Worksheet currentWorksheet;
33 private Metadata workbookMetadata;
34 private IPassword workbookProtectionPassword;
35 private bool lockWindowsIfProtected;
36 private bool lockStructureIfProtected;
37 private int selectedWorksheet;
38 private Shortener shortener;
39 private readonly List<string> mruColors = new List<string>();
40 internal bool importInProgress; // Used by NanoXLSX.Reader
41 #endregion
42
43 #region properties
44
49 internal AuxiliaryData AuxiliaryData { get; private set; }
50
55 {
56 get { return shortener; }
57 }
58
59
64 {
65 get { return currentWorksheet; }
66 }
67
74 public string Filename
75 {
76 get { return filename; }
77 set { filename = value; }
78 }
79
84 {
85 get { return lockStructureIfProtected; }
86 }
87
92 {
93 get { return lockWindowsIfProtected; }
94 }
95
100 {
101 get { return workbookMetadata; }
102 set { workbookMetadata = value; }
103 }
104
109 {
110 get { return selectedWorksheet; }
111 }
112
116 public bool UseWorkbookProtection { get; set; }
117
123 public virtual IPassword WorkbookProtectionPassword { get { return workbookProtectionPassword; } internal set => workbookProtectionPassword = value; }
124
128 public List<Worksheet> Worksheets
129 {
130 get { return worksheets; }
131 }
132
133
138 public bool Hidden { get; set; }
139
143 public Theme WorkbookTheme { get; set; } = Theme.GetDefaultTheme();
144
145
146 #endregion
147
148 #region constructors
152 public Workbook()
153 {
154 Init();
155 }
156
161 public Workbook(bool createWorkSheet)
162 {
163 Init();
164 if (createWorkSheet)
165 {
166 AddWorksheet("Sheet1");
167 }
168 }
169
174 public Workbook(string sheetName)
175 {
176 Init();
177 AddWorksheet(sheetName, true);
178 }
179
185 public Workbook(string filename, string sheetName)
186 {
187 Init();
188 this.filename = filename;
189 AddWorksheet(sheetName, true);
190 }
191
198 public Workbook(string filename, string sheetName, bool sanitizeSheetName)
199 {
200 Init();
201 this.filename = filename;
202 if (sanitizeSheetName)
203 {
205 }
206 else
207 {
208 AddWorksheet(sheetName);
209 }
210 }
211
212 #endregion
213
214 #region methods
215
220 public void AddMruColor(string color)
221 {
222 if (color != null && color.Length == 6)
223 {
224 color = "FF" + color;
225 }
226 Validators.ValidateColor(color, true);
227 mruColors.Add(ParserUtils.ToUpper(color));
228 }
229
234 public IReadOnlyList<string> GetMruColors()
235 {
236 return mruColors;
237 }
238
242 public void ClearMruColors()
243 {
244 mruColors.Clear();
245 }
246
253 public void AddWorksheet(string name)
254 {
255 foreach (Worksheet item in worksheets)
256 {
257 if (item.SheetName == name)
258 {
259 throw new WorksheetException("The worksheet with the name '" + name + "' already exists.");
260 }
261 }
262 int number = GetNextWorksheetId();
263 Worksheet newWs = new Worksheet(name, number, this);
264 currentWorksheet = newWs;
265 worksheets.Add(newWs);
266 shortener.SetCurrentWorksheetInternal(currentWorksheet);
267 }
268
276 public void AddWorksheet(string name, bool sanitizeSheetName)
277 {
278 if (sanitizeSheetName)
279 {
280 string sanitized = Worksheet.SanitizeWorksheetName(name, this);
281 AddWorksheet(sanitized);
282 }
283 else
284 {
285 AddWorksheet(name);
286 }
287 }
288
295 public void AddWorksheet(Worksheet worksheet)
296 {
297 AddWorksheet(worksheet, false);
298 }
299
307 public void AddWorksheet(Worksheet worksheet, bool sanitizeSheetName)
308 {
309 if (sanitizeSheetName)
310 {
311 string name = Worksheet.SanitizeWorksheetName(worksheet.SheetName, this);
312 worksheet.SheetName = name;
313 }
314 else
315 {
316 if (string.IsNullOrEmpty(worksheet.SheetName))
317 {
318 throw new WorksheetException("The name of the passed worksheet is null or empty.");
319 }
320 for (int i = 0; i < worksheets.Count; i++)
321 {
322 if (worksheets[i].SheetName == worksheet.SheetName)
323 {
324 throw new WorksheetException("The worksheet with the name '" + worksheet.SheetName + "' already exists.");
325 }
326 }
327 }
328 worksheet.SheetID = GetNextWorksheetId();
329 currentWorksheet = worksheet;
330 worksheets.Add(worksheet);
331 worksheet.WorkbookReference = this;
332 }
333
340 public void RemoveWorksheet(string name)
341 {
342 Worksheet worksheetToRemove = worksheets.FirstOrDefault(w => w.SheetName == name);
343 if (worksheetToRemove == null)
344 {
345 throw new WorksheetException("The worksheet with the name '" + name + "' does not exist.");
346 }
347 int index = worksheets.IndexOf(worksheetToRemove);
348 bool resetCurrentWorksheet = worksheetToRemove == currentWorksheet;
349 RemoveWorksheet(index, resetCurrentWorksheet);
350 }
351
358
359 public void RemoveWorksheet(int index)
360 {
361 if (index < 0 || index >= worksheets.Count)
362 {
363 throw new WorksheetException("The worksheet index " + index + " is out of range");
364 }
365 bool resetCurrentWorksheet = worksheets[index] == currentWorksheet;
366 RemoveWorksheet(index, resetCurrentWorksheet);
367 }
368
374 internal void ResolveMergedCells()
375 {
376 foreach (Worksheet worksheet in worksheets)
377 {
378 worksheet.ResolveMergedCells();
379 }
380 }
381
388 public Worksheet SetCurrentWorksheet(string name)
389 {
390 currentWorksheet = GetWorksheet(name);
391 shortener.SetCurrentWorksheetInternal(currentWorksheet);
392 return currentWorksheet;
393 }
394
401 public Worksheet SetCurrentWorksheet(int worksheetIndex)
402 {
403 currentWorksheet = GetWorksheet(worksheetIndex);
404 shortener.SetCurrentWorksheetInternal(currentWorksheet);
405 return currentWorksheet;
406 }
407
413 public void SetCurrentWorksheet(Worksheet worksheet)
414 {
415 int index = worksheets.IndexOf(worksheet);
416 if (index < 0)
417 {
418 throw new WorksheetException("The passed worksheet object is not in the worksheet collection.");
419 }
420 currentWorksheet = worksheets[index];
421 shortener.SetCurrentWorksheetInternal(worksheet);
422 }
423
429 public void SetSelectedWorksheet(string name)
430 {
431 int index = worksheets.FindIndex(w => w.SheetName == name);
432 if (index < 0)
433 {
434 throw new WorksheetException("No worksheet with the name '" + name + "' was found in this workbook.");
435 }
436 selectedWorksheet = index;
437 }
438
446 public void SetSelectedWorksheet(int worksheetIndex)
447 {
448 if (worksheetIndex < 0 || worksheetIndex > worksheets.Count - 1)
449 {
450 throw new RangeException("The worksheet index " + worksheetIndex + " is out of range");
451 }
452 selectedWorksheet = worksheetIndex;
453 ValidateWorksheets();
454 }
455
462 public void SetSelectedWorksheet(Worksheet worksheet)
463 {
464 selectedWorksheet = worksheets.IndexOf(worksheet);
465 if (selectedWorksheet < 0)
466 {
467 throw new WorksheetException("The passed worksheet object is not in the worksheet collection.");
468 }
469 ValidateWorksheets();
470 }
471
478 public Worksheet GetWorksheet(string name)
479 {
480 int index = worksheets.FindIndex(w => w.SheetName == name);
481 if (index < 0)
482 {
483 throw new WorksheetException("No worksheet with the name '" + name + "' was found in this workbook.");
484 }
485 return worksheets[index];
486 }
487
494 public Worksheet GetWorksheet(int index)
495 {
496 if (index < 0 || index > worksheets.Count - 1)
497 {
498 throw new RangeException("The worksheet index " + index + " is out of range");
499 }
500 return worksheets[index];
501 }
502
510 public void SetWorkbookProtection(bool state, bool protectWindows, bool protectStructure, string password)
511 {
512 lockWindowsIfProtected = protectWindows;
513 lockStructureIfProtected = protectStructure;
514 workbookProtectionPassword.SetPassword(password);
515 if (!protectWindows && !protectStructure)
516 {
517 UseWorkbookProtection = false;
518 }
519 else
520 {
521 UseWorkbookProtection = state;
522 }
523 }
524
533 public Worksheet CopyWorksheetIntoThis(string sourceWorksheetName, string newWorksheetName, bool sanitizeSheetName = true)
534 {
535 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetName);
536 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
537 }
538
547 public Worksheet CopyWorksheetIntoThis(int sourceWorksheetIndex, string newWorksheetName, bool sanitizeSheetName = true)
548 {
549 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetIndex);
550 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
551 }
552
561 public Worksheet CopyWorksheetIntoThis(Worksheet sourceWorksheet, string newWorksheetName, bool sanitizeSheetName = true)
562 {
563 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
564 }
565
575 public Worksheet CopyWorksheetTo(string sourceWorksheetName, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
576 {
577 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetName);
578 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, targetWorkbook, sanitizeSheetName);
579 }
580
590 public Worksheet CopyWorksheetTo(int sourceWorksheetIndex, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
591 {
592 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetIndex);
593 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, targetWorkbook, sanitizeSheetName);
594 }
595
596
606 public static Worksheet CopyWorksheetTo(Worksheet sourceWorksheet, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
607 {
608 if (targetWorkbook == null)
609 {
610 throw new WorksheetException("The target workbook cannot be null");
611 }
612 if (sourceWorksheet == null)
613 {
614 throw new WorksheetException("The source worksheet cannot be null");
615 }
616 Worksheet copy = sourceWorksheet.Copy();
617 copy.SetSheetName(newWorksheetName);
618 Worksheet currentWorksheet = targetWorkbook.CurrentWorksheet;
619 targetWorkbook.AddWorksheet(copy, sanitizeSheetName);
620 targetWorkbook.SetCurrentWorksheet(currentWorksheet);
621 return copy;
622 }
623
624
633 internal void ValidateWorksheets()
634 {
635 if (importInProgress)
636 {
637 // No validation during import
638 return;
639 }
640 int worksheetCount = worksheets.Count;
641 if (worksheetCount == 0)
642 {
643 throw new WorksheetException("The workbook must contain at least one worksheet");
644 }
645 for (int i = 0; i < worksheetCount; i++)
646 {
647 if (worksheets[i].Hidden)
648 {
649 if (i == selectedWorksheet)
650 {
651 throw new WorksheetException("The worksheet with the index " + selectedWorksheet + " cannot be set as selected, since it is set hidden");
652 }
653 }
654 }
655 }
656
662 private void RemoveWorksheet(int index, bool resetCurrentWorksheet)
663 {
664 worksheets.RemoveAt(index);
665 if (worksheets.Count > 0)
666 {
667 for (int i = 0; i < worksheets.Count; i++)
668 {
669 worksheets[i].SheetID = i + 1;
670 }
671 if (resetCurrentWorksheet)
672 {
673 currentWorksheet = worksheets[worksheets.Count - 1];
674 }
675 if (selectedWorksheet == index || selectedWorksheet > worksheets.Count - 1)
676 {
677 selectedWorksheet = worksheets.Count - 1;
678 }
679 }
680 else
681 {
682 currentWorksheet = null;
683 selectedWorksheet = 0;
684 }
685 ValidateWorksheets();
686 }
687
692 private int GetNextWorksheetId()
693 {
694 if (worksheets.Count == 0)
695 {
696 return 1;
697 }
698 return worksheets.Max(w => w.SheetID) + 1;
699 }
700
704 private void Init()
705 {
706 worksheets = new List<Worksheet>();
707 workbookMetadata = new Metadata();
708 shortener = new Shortener(this);
709 workbookProtectionPassword = new LegacyPassword(LegacyPassword.PasswordType.WorkbookProtection);
710 AuxiliaryData = new AuxiliaryData();
711 }
712
713
714 #endregion
715 }
716}
Class for exceptions regarding range incidents (e.g. out-of-range).
Class for exceptions regarding worksheet incidents.
Class representing the metadata of a workbook.
Definition Metadata.cs:19
Class to register plug-in classes that extends the functionality of NanoXLSX (Core or any other packa...
static bool Initialize()
Initializes the plug-in loader process. If already initialized, the method returns without action.
Class to provide access to the current worksheet with a shortened syntax.
Definition Shortener.cs:19
Class representing an Office theme.
Definition Theme.cs:16
Class providing static methods to parse string values to specific types or to print object as languag...
static string ToUpper(string input)
Transforms a string to upper case with null check and invariant culture.
Class providing general validator methods.
Definition Validators.cs:11
static void ValidateColor(string hexCode, bool useAlpha, bool allowEmpty=false)
Validates the passed string, whether it is a valid RGB or ARGB value that can be used for Fills or Fo...
Definition Validators.cs:25
void AddWorksheet(Worksheet worksheet, bool sanitizeSheetName)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:307
bool Hidden
Gets or sets whether the whole workbook is hidden.
Definition Workbook.cs:138
Workbook(string filename, string sheetName, bool sanitizeSheetName)
Constructor with filename ant the name of the first worksheet.
Definition Workbook.cs:198
void SetSelectedWorksheet(Worksheet worksheet)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:462
void AddMruColor(string color)
Adds a color value (HEX; 6-digit RGB or 8-digit ARGB) to the MRU list.
Definition Workbook.cs:220
Workbook()
Default constructor. No initial worksheet is created. Use AddWorksheet(string) (or overloads) to add ...
Definition Workbook.cs:152
void ClearMruColors()
Clears the MRU color list.
Definition Workbook.cs:242
void SetCurrentWorksheet(Worksheet worksheet)
Sets the current worksheet.
Definition Workbook.cs:413
void SetSelectedWorksheet(int worksheetIndex)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:446
IReadOnlyList< string > GetMruColors()
Gets the MRU color list.
Definition Workbook.cs:234
int SelectedWorksheet
Gets the selected worksheet. The selected worksheet is not the current worksheet while design time bu...
Definition Workbook.cs:109
void AddWorksheet(string name, bool sanitizeSheetName)
Adding a new Worksheet with a sanitizing option. The new worksheet will be defined as current workshe...
Definition Workbook.cs:276
void RemoveWorksheet(int index)
Removes the defined worksheet based on its index. If the worksheet is the current or selected workshe...
Definition Workbook.cs:359
Worksheet CopyWorksheetIntoThis(int sourceWorksheetIndex, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its index.
Definition Workbook.cs:547
Shortener WS
Gets the shortener object for the current worksheet.
Definition Workbook.cs:55
void SetWorkbookProtection(bool state, bool protectWindows, bool protectStructure, string password)
Sets or removes the workbook protection. If protectWindows and protectStructure are both false,...
Definition Workbook.cs:510
Theme WorkbookTheme
Gets or sets the theme of the workbook. The default is defined by Theme.GetDefaultTheme....
Definition Workbook.cs:143
string Filename
Gets or sets the filename of the workbook.
Definition Workbook.cs:75
Workbook(string sheetName)
Constructor with additional parameter to create a default worksheet with the specified name....
Definition Workbook.cs:174
Workbook(bool createWorkSheet)
Constructor with additional parameter to create a default worksheet. This constructor can be used to ...
Definition Workbook.cs:161
void AddWorksheet(Worksheet worksheet)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:295
Worksheet GetWorksheet(int index)
Gets a worksheet from this workbook by index.
Definition Workbook.cs:494
bool LockStructureIfProtected
Gets whether the structure are locked if workbook is protected. See also SetWorkbookProtection.
Definition Workbook.cs:84
Workbook(string filename, string sheetName)
Constructor with filename ant the name of the first worksheet.
Definition Workbook.cs:185
void SetSelectedWorksheet(string name)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:429
Worksheet SetCurrentWorksheet(int worksheetIndex)
Sets the current worksheet.
Definition Workbook.cs:401
Worksheet CopyWorksheetTo(string sourceWorksheetName, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its name into another workbook.
Definition Workbook.cs:575
Worksheet CurrentWorksheet
Gets the current worksheet.
Definition Workbook.cs:64
Worksheet CopyWorksheetTo(int sourceWorksheetIndex, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its index into another workbook.
Definition Workbook.cs:590
List< Worksheet > Worksheets
Gets the list of worksheets in the workbook.
Definition Workbook.cs:129
void AddWorksheet(string name)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:253
Metadata WorkbookMetadata
Meta data object of the workbook.
Definition Workbook.cs:100
bool LockWindowsIfProtected
Gets whether the windows are locked if workbook is protected. See also SetWorkbookProtection.
Definition Workbook.cs:92
bool UseWorkbookProtection
Gets or sets whether the workbook is protected.
Definition Workbook.cs:116
virtual IPassword WorkbookProtectionPassword
Password instance of the protected workbook. If a password was set, the pain text representation and ...
Definition Workbook.cs:123
Worksheet CopyWorksheetIntoThis(Worksheet sourceWorksheet, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of any workbook into the current workbook.
Definition Workbook.cs:561
Worksheet CopyWorksheetIntoThis(string sourceWorksheetName, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its name.
Definition Workbook.cs:533
Worksheet SetCurrentWorksheet(string name)
Sets the current worksheet.
Definition Workbook.cs:388
void RemoveWorksheet(string name)
Removes the defined worksheet based on its name. If the worksheet is the current or selected workshee...
Definition Workbook.cs:340
Worksheet GetWorksheet(string name)
Gets a worksheet from this workbook by name.
Definition Workbook.cs:478
static Worksheet CopyWorksheetTo(Worksheet sourceWorksheet, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName=true)
Copies a worksheet of any workbook into the another workbook.
Definition Workbook.cs:606
Class representing a worksheet of a workbook.
Definition Worksheet.cs:26
Worksheet Copy()
Creates a (dereferenced) deep copy of this worksheet.
string SheetName
Gets or sets the name of the worksheet.
Definition Worksheet.cs:329
void SetSheetName(string name)
Validates and sets the worksheet name.
static string SanitizeWorksheetName(string input, Workbook workbook)
Sanitizes a worksheet name.
Interface to represent a protection password, either for workbooks or worksheets. The implementations...
Definition IPassword.cs:14