NanoXLSX.Core 3.0.0-rc.4
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;
10using NanoXLSX.Colors;
14using NanoXLSX.Themes;
15using NanoXLSX.Utils;
16
17namespace NanoXLSX
18{
23 public class Workbook
24 {
25 static Workbook()
26 {
28 }
29
30 #region privateFields
31 private string filename;
32 private List<Worksheet> worksheets;
33 private Worksheet currentWorksheet;
34 private Metadata workbookMetadata;
35 private IPassword workbookProtectionPassword;
36 private bool lockWindowsIfProtected;
37 private bool lockStructureIfProtected;
38 private int selectedWorksheet;
39 private Shortener shortener;
40 private readonly List<Color> mruColors = new List<Color>();
41 internal bool importInProgress; // Used by NanoXLSX.Reader
42 #endregion
43
44 #region properties
45
50 internal AuxiliaryData AuxiliaryData { get; private set; }
51
56 {
57 get { return shortener; }
58 }
59
60
65 {
66 get { return currentWorksheet; }
67 }
68
75 public string Filename
76 {
77 get { return filename; }
78 set { filename = value; }
79 }
80
85 {
86 get { return lockStructureIfProtected; }
87 }
88
93 {
94 get { return lockWindowsIfProtected; }
95 }
96
101 {
102 get { return workbookMetadata; }
103 set { workbookMetadata = value; }
104 }
105
110 {
111 get { return selectedWorksheet; }
112 }
113
117 public bool UseWorkbookProtection { get; set; }
118
124 public virtual IPassword WorkbookProtectionPassword { get { return workbookProtectionPassword; } internal set => workbookProtectionPassword = value; }
125
129 public List<Worksheet> Worksheets
130 {
131 get { return worksheets; }
132 }
133
134
139 public bool Hidden { get; set; }
140
144 public Theme WorkbookTheme { get; set; } = Theme.GetDefaultTheme();
145
146
147 #endregion
148
149 #region constructors
153 public Workbook()
154 {
155 Init();
156 }
157
162 public Workbook(bool createWorkSheet)
163 {
164 Init();
165 if (createWorkSheet)
166 {
167 AddWorksheet("Sheet1");
168 }
169 }
170
175 public Workbook(string sheetName)
176 {
177 Init();
178 AddWorksheet(sheetName, true);
179 }
180
186 public Workbook(string filename, string sheetName)
187 {
188 Init();
189 this.filename = filename;
190 AddWorksheet(sheetName, true);
191 }
192
199 public Workbook(string filename, string sheetName, bool sanitizeSheetName)
200 {
201 Init();
202 this.filename = filename;
203 if (sanitizeSheetName)
204 {
206 }
207 else
208 {
209 AddWorksheet(sheetName);
210 }
211 }
212
213 #endregion
214
215 #region methods
216
221 public void AddMruColor(string color)
222 {
224 mruColors.Add(Color.CreateRgb(color));
225 }
226
231 public void AddMruColor(Color color)
232 {
233 mruColors.Add(color);
234 }
235
240 public IReadOnlyList<Color> GetMruColors()
241 {
242 return mruColors;
243 }
244
248 public void ClearMruColors()
249 {
250 mruColors.Clear();
251 }
252
259 public void AddWorksheet(string name)
260 {
261 foreach (Worksheet item in worksheets)
262 {
263 if (item.SheetName == name)
264 {
265 throw new WorksheetException("The worksheet with the name '" + name + "' already exists.");
266 }
267 }
268 int number = GetNextWorksheetId();
269 Worksheet newWs = new Worksheet(name, number, this);
270 currentWorksheet = newWs;
271 worksheets.Add(newWs);
272 shortener.SetCurrentWorksheetInternal(currentWorksheet);
273 }
274
282 public void AddWorksheet(string name, bool sanitizeSheetName)
283 {
284 if (sanitizeSheetName)
285 {
286 string sanitized = Worksheet.SanitizeWorksheetName(name, this);
287 AddWorksheet(sanitized);
288 }
289 else
290 {
291 AddWorksheet(name);
292 }
293 }
294
301 public void AddWorksheet(Worksheet worksheet)
302 {
303 AddWorksheet(worksheet, false);
304 }
305
313 public void AddWorksheet(Worksheet worksheet, bool sanitizeSheetName)
314 {
315 if (sanitizeSheetName)
316 {
317 string name = Worksheet.SanitizeWorksheetName(worksheet.SheetName, this);
318 worksheet.SheetName = name;
319 }
320 else
321 {
322 if (string.IsNullOrEmpty(worksheet.SheetName))
323 {
324 throw new WorksheetException("The name of the passed worksheet is null or empty.");
325 }
326 for (int i = 0; i < worksheets.Count; i++)
327 {
328 if (worksheets[i].SheetName == worksheet.SheetName)
329 {
330 throw new WorksheetException("The worksheet with the name '" + worksheet.SheetName + "' already exists.");
331 }
332 }
333 }
334 worksheet.SheetID = GetNextWorksheetId();
335 currentWorksheet = worksheet;
336 worksheets.Add(worksheet);
337 worksheet.WorkbookReference = this;
338 }
339
346 public void RemoveWorksheet(string name)
347 {
348 Worksheet worksheetToRemove = worksheets.FirstOrDefault(w => w.SheetName == name);
349 if (worksheetToRemove == null)
350 {
351 throw new WorksheetException("The worksheet with the name '" + name + "' does not exist.");
352 }
353 int index = worksheets.IndexOf(worksheetToRemove);
354 bool resetCurrentWorksheet = worksheetToRemove == currentWorksheet;
355 RemoveWorksheet(index, resetCurrentWorksheet);
356 }
357
364
365 public void RemoveWorksheet(int index)
366 {
367 if (index < 0 || index >= worksheets.Count)
368 {
369 throw new WorksheetException("The worksheet index " + index + " is out of range");
370 }
371 bool resetCurrentWorksheet = worksheets[index] == currentWorksheet;
372 RemoveWorksheet(index, resetCurrentWorksheet);
373 }
374
380 internal void ResolveMergedCells()
381 {
382 foreach (Worksheet worksheet in worksheets)
383 {
384 worksheet.ResolveMergedCells();
385 }
386 }
387
394 public Worksheet SetCurrentWorksheet(string name)
395 {
396 currentWorksheet = GetWorksheet(name);
397 shortener.SetCurrentWorksheetInternal(currentWorksheet);
398 return currentWorksheet;
399 }
400
407 public Worksheet SetCurrentWorksheet(int worksheetIndex)
408 {
409 currentWorksheet = GetWorksheet(worksheetIndex);
410 shortener.SetCurrentWorksheetInternal(currentWorksheet);
411 return currentWorksheet;
412 }
413
419 public void SetCurrentWorksheet(Worksheet worksheet)
420 {
421 int index = worksheets.IndexOf(worksheet);
422 if (index < 0)
423 {
424 throw new WorksheetException("The passed worksheet object is not in the worksheet collection.");
425 }
426 currentWorksheet = worksheets[index];
427 shortener.SetCurrentWorksheetInternal(worksheet);
428 }
429
435 public void SetSelectedWorksheet(string name)
436 {
437 int index = worksheets.FindIndex(w => w.SheetName == name);
438 if (index < 0)
439 {
440 throw new WorksheetException("No worksheet with the name '" + name + "' was found in this workbook.");
441 }
442 selectedWorksheet = index;
443 }
444
452 public void SetSelectedWorksheet(int worksheetIndex)
453 {
454 if (worksheetIndex < 0 || worksheetIndex > worksheets.Count - 1)
455 {
456 throw new RangeException("The worksheet index " + worksheetIndex + " is out of range");
457 }
458 selectedWorksheet = worksheetIndex;
459 ValidateWorksheets();
460 }
461
468 public void SetSelectedWorksheet(Worksheet worksheet)
469 {
470 selectedWorksheet = worksheets.IndexOf(worksheet);
471 if (selectedWorksheet < 0)
472 {
473 throw new WorksheetException("The passed worksheet object is not in the worksheet collection.");
474 }
475 ValidateWorksheets();
476 }
477
484 public Worksheet GetWorksheet(string name)
485 {
486 int index = worksheets.FindIndex(w => w.SheetName == name);
487 if (index < 0)
488 {
489 throw new WorksheetException("No worksheet with the name '" + name + "' was found in this workbook.");
490 }
491 return worksheets[index];
492 }
493
500 public Worksheet GetWorksheet(int index)
501 {
502 if (index < 0 || index > worksheets.Count - 1)
503 {
504 throw new RangeException("The worksheet index " + index + " is out of range");
505 }
506 return worksheets[index];
507 }
508
516 public void SetWorkbookProtection(bool state, bool protectWindows, bool protectStructure, string password)
517 {
518 lockWindowsIfProtected = protectWindows;
519 lockStructureIfProtected = protectStructure;
520 workbookProtectionPassword.SetPassword(password);
521 if (!protectWindows && !protectStructure)
522 {
523 UseWorkbookProtection = false;
524 }
525 else
526 {
527 UseWorkbookProtection = state;
528 }
529 }
530
539 public Worksheet CopyWorksheetIntoThis(string sourceWorksheetName, string newWorksheetName, bool sanitizeSheetName = true)
540 {
541 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetName);
542 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
543 }
544
553 public Worksheet CopyWorksheetIntoThis(int sourceWorksheetIndex, string newWorksheetName, bool sanitizeSheetName = true)
554 {
555 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetIndex);
556 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
557 }
558
567 public Worksheet CopyWorksheetIntoThis(Worksheet sourceWorksheet, string newWorksheetName, bool sanitizeSheetName = true)
568 {
569 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, this, sanitizeSheetName);
570 }
571
581 public Worksheet CopyWorksheetTo(string sourceWorksheetName, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
582 {
583 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetName);
584 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, targetWorkbook, sanitizeSheetName);
585 }
586
596 public Worksheet CopyWorksheetTo(int sourceWorksheetIndex, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
597 {
598 Worksheet sourceWorksheet = GetWorksheet(sourceWorksheetIndex);
599 return CopyWorksheetTo(sourceWorksheet, newWorksheetName, targetWorkbook, sanitizeSheetName);
600 }
601
602
612 public static Worksheet CopyWorksheetTo(Worksheet sourceWorksheet, string newWorksheetName, Workbook targetWorkbook, bool sanitizeSheetName = true)
613 {
614 if (targetWorkbook == null)
615 {
616 throw new WorksheetException("The target workbook cannot be null");
617 }
618 if (sourceWorksheet == null)
619 {
620 throw new WorksheetException("The source worksheet cannot be null");
621 }
622 Worksheet copy = sourceWorksheet.Copy();
623 copy.SetSheetName(newWorksheetName);
624 Worksheet currentWorksheet = targetWorkbook.CurrentWorksheet;
625 targetWorkbook.AddWorksheet(copy, sanitizeSheetName);
626 targetWorkbook.SetCurrentWorksheet(currentWorksheet);
627 return copy;
628 }
629
630
639 internal void ValidateWorksheets()
640 {
641 if (importInProgress)
642 {
643 // No validation during import
644 return;
645 }
646 int worksheetCount = worksheets.Count;
647 if (worksheetCount == 0)
648 {
649 throw new WorksheetException("The workbook must contain at least one worksheet");
650 }
651 for (int i = 0; i < worksheetCount; i++)
652 {
653 if (worksheets[i].Hidden)
654 {
655 if (i == selectedWorksheet)
656 {
657 throw new WorksheetException("The worksheet with the index " + selectedWorksheet + " cannot be set as selected, since it is set hidden");
658 }
659 }
660 }
661 }
662
668 private void RemoveWorksheet(int index, bool resetCurrentWorksheet)
669 {
670 worksheets.RemoveAt(index);
671 if (worksheets.Count > 0)
672 {
673 for (int i = 0; i < worksheets.Count; i++)
674 {
675 worksheets[i].SheetID = i + 1;
676 }
677 if (resetCurrentWorksheet)
678 {
679 currentWorksheet = worksheets[worksheets.Count - 1];
680 }
681 if (selectedWorksheet == index || selectedWorksheet > worksheets.Count - 1)
682 {
683 selectedWorksheet = worksheets.Count - 1;
684 }
685 }
686 else
687 {
688 currentWorksheet = null;
689 selectedWorksheet = 0;
690 }
691 ValidateWorksheets();
692 }
693
698 private int GetNextWorksheetId()
699 {
700 if (worksheets.Count == 0)
701 {
702 return 1;
703 }
704 return worksheets.Max(w => w.SheetID) + 1;
705 }
706
710 private void Init()
711 {
712 worksheets = new List<Worksheet>();
713 workbookMetadata = new Metadata();
714 shortener = new Shortener(this);
715 workbookProtectionPassword = new LegacyPassword(LegacyPassword.PasswordType.WorkbookProtection);
716 AuxiliaryData = new AuxiliaryData();
717 }
718
719
720 #endregion
721 }
722}
Compound class representing a color in various representations (RGB, indexed, theme,...
Definition Color.cs:20
static Color CreateRgb(SrgbColor color)
Creates an Color from an RGB/ARGB color.
Definition Color.cs:171
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:17
Class providing general validator methods.
Definition Validators.cs:11
static void ValidateGenericColor(string hexCode, bool allowEmpty=false)
Validates the passed string, whether it is a valid RGB or ARGB value that can be used for Fills,...
Definition Validators.cs:19
void AddWorksheet(Worksheet worksheet, bool sanitizeSheetName)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:313
bool Hidden
Gets or sets whether the whole workbook is hidden.
Definition Workbook.cs:139
Workbook(string filename, string sheetName, bool sanitizeSheetName)
Constructor with filename ant the name of the first worksheet.
Definition Workbook.cs:199
void SetSelectedWorksheet(Worksheet worksheet)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:468
void AddMruColor(string color)
Adds a color value (HEX; 6-digit RGB or 8-digit ARGB) to the MRU list.
Definition Workbook.cs:221
Workbook()
Default constructor. No initial worksheet is created. Use AddWorksheet(string) (or overloads) to add ...
Definition Workbook.cs:153
void ClearMruColors()
Clears the MRU color list.
Definition Workbook.cs:248
void SetCurrentWorksheet(Worksheet worksheet)
Sets the current worksheet.
Definition Workbook.cs:419
void SetSelectedWorksheet(int worksheetIndex)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:452
int SelectedWorksheet
Gets the selected worksheet. The selected worksheet is not the current worksheet while design time bu...
Definition Workbook.cs:110
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:282
void RemoveWorksheet(int index)
Removes the defined worksheet based on its index. If the worksheet is the current or selected workshe...
Definition Workbook.cs:365
Worksheet CopyWorksheetIntoThis(int sourceWorksheetIndex, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its index.
Definition Workbook.cs:553
Shortener WS
Gets the shortener object for the current worksheet.
Definition Workbook.cs:56
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:516
Theme WorkbookTheme
Gets or sets the theme of the workbook. The default is defined by Theme.GetDefaultTheme....
Definition Workbook.cs:144
string Filename
Gets or sets the filename of the workbook.
Definition Workbook.cs:76
Workbook(string sheetName)
Constructor with additional parameter to create a default worksheet with the specified name....
Definition Workbook.cs:175
Workbook(bool createWorkSheet)
Constructor with additional parameter to create a default worksheet. This constructor can be used to ...
Definition Workbook.cs:162
void AddWorksheet(Worksheet worksheet)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:301
IReadOnlyList< Color > GetMruColors()
Gets the MRU color list.
Definition Workbook.cs:240
Worksheet GetWorksheet(int index)
Gets a worksheet from this workbook by index.
Definition Workbook.cs:500
bool LockStructureIfProtected
Gets whether the structure are locked if workbook is protected. See also SetWorkbookProtection.
Definition Workbook.cs:85
Workbook(string filename, string sheetName)
Constructor with filename ant the name of the first worksheet.
Definition Workbook.cs:186
void SetSelectedWorksheet(string name)
Sets the selected worksheet in the output workbook.
Definition Workbook.cs:435
Worksheet SetCurrentWorksheet(int worksheetIndex)
Sets the current worksheet.
Definition Workbook.cs:407
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:581
void AddMruColor(Color color)
Adds a generic color value. This can be an RGB/ARGB color, Auto, Theme, Indexed or System color.
Definition Workbook.cs:231
Worksheet CurrentWorksheet
Gets the current worksheet.
Definition Workbook.cs:65
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:596
List< Worksheet > Worksheets
Gets the list of worksheets in the workbook.
Definition Workbook.cs:130
void AddWorksheet(string name)
Adding a new Worksheet. The new worksheet will be defined as current worksheet.
Definition Workbook.cs:259
Metadata WorkbookMetadata
Meta data object of the workbook.
Definition Workbook.cs:101
bool LockWindowsIfProtected
Gets whether the windows are locked if workbook is protected. See also SetWorkbookProtection.
Definition Workbook.cs:93
bool UseWorkbookProtection
Gets or sets whether the workbook is protected.
Definition Workbook.cs:117
virtual IPassword WorkbookProtectionPassword
Password instance of the protected workbook. If a password was set, the pain text representation and ...
Definition Workbook.cs:124
Worksheet CopyWorksheetIntoThis(Worksheet sourceWorksheet, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of any workbook into the current workbook.
Definition Workbook.cs:567
Worksheet CopyWorksheetIntoThis(string sourceWorksheetName, string newWorksheetName, bool sanitizeSheetName=true)
Copies a worksheet of the current workbook by its name.
Definition Workbook.cs:539
Worksheet SetCurrentWorksheet(string name)
Sets the current worksheet.
Definition Workbook.cs:394
void RemoveWorksheet(string name)
Removes the defined worksheet based on its name. If the worksheet is the current or selected workshee...
Definition Workbook.cs:346
Worksheet GetWorksheet(string name)
Gets a worksheet from this workbook by name.
Definition Workbook.cs:484
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:612
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