18using System.Collections.Generic;
24 internal class ExcelHelper
27 internal static void TokenizeExcelFile(GPALFile gPALFile)
29 foreach (
string filename
in gPALFile.Filenames)
33 IGPALGrid<string> data = GPAL.Grid.ToGPALObject();
35 using (var workbook =
new XLWorkbook(filename))
37 var worksheet = workbook.Worksheet(1);
39 foreach (var row
in worksheet.RowsUsed())
41 var rowData =
new List<string>();
42 foreach (var cell
in row.CellsUsed())
44 rowData.Add(cell.GetString());
48 ((IGPALFileInternal)gPALFile).FileGrid.Add(data);
53 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Unable to tokenize file [{filename}]. Continuing.", gPALFile, Enums.GPALObjectType.GPALFile, ex);
58 internal static IGPALGrid<string> TokenizeExcelFile(
string filename)
60 IGPALGrid<string> data = GPAL.Grid.ToGPALObject();
64 using (var workbook =
new XLWorkbook(filename))
66 foreach (IXLWorksheet worksheet
in workbook.Worksheets)
68 var lastRow = worksheet.LastRowUsed()?.RowNumber() ?? 0;
69 var lastCol = worksheet.LastColumnUsed()?.ColumnNumber() ?? 0;
71 for (
int r = 1; r <= lastRow; r++)
73 var rowData =
new List<string>();
74 var row = worksheet.Row(r);
76 for (
int c = 1; c <= lastCol; c++)
78 rowData.Add(row.Cell(c).GetString());
88 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION,
89 $
"Unable to tokenize file [{filename}]. Continuing.",
null,
90 Enums.GPALObjectType.None, ex);
102 internal static void CopyWorksheet(IXLWorksheet src, IXLWorksheet dest)
110 foreach (var row
in src.RowsUsed())
112 int rowIndex = row.RowNumber();
113 foreach (var cell
in row.CellsUsed())
115 int colIndex = cell.Address.ColumnNumber;
117 dest.Cell(rowIndex, colIndex).Value = cell.GetString();
123 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to copy worksheet",
null, Enums.GPALObjectType.None, ex);
132 internal static void WriteRange(IXLWorksheet worksheet,
string range, IGPALGrid<string> data)
136 var rangeObj = worksheet.Range(range);
137 var firstCell = rangeObj.FirstCell();
139 int startRow = firstCell.Address.RowNumber;
140 int startColumn = firstCell.Address.ColumnNumber;
142 for (
int rowIndex = 0; rowIndex < data.Count(); rowIndex++)
144 var row = data[rowIndex];
145 for (
int colIndex = 0; colIndex < row.Count; colIndex++)
147 worksheet.Cell(startRow + rowIndex, startColumn + colIndex).Value = row[colIndex];
153 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to write range [{range}] in worksheet",
null, Enums.GPALObjectType.None, ex);
160 public string CellAddress {
get;
set; }
161 public string OldValue {
get;
set; }
162 public string NewValue {
get;
set; }
163 public string SourceRange {
get;
set; }
164 public string TargetRange {
get;
set; }
174 internal static List<CellDifference> CompareRanges(IGPALGrid<string> data1, IGPALGrid<string> data2)
176 var differences =
new List<CellDifference>();
180 int maxRows = Math.Max(data1.Count(), data2.Count());
181 int maxCols = Math.Max(data1.Any() ? data1[0].Count : 0, data2.Any() ? data2[0].Count : 0);
183 for (
int i = 0; i < maxRows; i++)
185 for (
int j = 0; j < maxCols; j++)
187 string value1 = i < data1.Count() && j < data1[i].Count ? data1[i][j] :
null;
188 string value2 = i < data2.Count() && j < data2[i].Count ? data2[i][j] :
null;
190 if (value1 != value2)
192 string cellAddress = $
"{(char)('A' + j)}{i + 1}";
195 CellAddress = cellAddress,
196 OldValue = value1 ??
"",
197 NewValue = value2 ??
""
205 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to compare ranges",
null, Enums.GPALObjectType.None, ex);
212 internal static IGPALGrid<string> ReadRange(IXLWorksheet worksheet,
string range)
214 IGPALGrid<string> data = GPAL.Grid.ToGPALObject();
218 var xlRange = worksheet.Range(range);
220 foreach (var row
in xlRange.RowsUsed())
222 var rowData =
new List<string>();
223 foreach (var cell
in row.CellsUsed())
225 rowData.Add(cell.GetString());
227 data.AddRow(rowData);
232 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to extract range [{range}]",
null, Enums.GPALObjectType.None, ex);
240 internal static List<string> GetColumnValues(IXLWorksheet worksheet,
string column)
242 var values =
new List<string>();
246 var col = worksheet.Column(column);
247 foreach (var cell
in col.CellsUsed())
249 values.Add(cell.GetString());
254 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to get values for column [{column}]",
null, Enums.GPALObjectType.None, ex);
260 internal static List<string> GetRowValues(IXLWorksheet worksheet,
int rowNumber)
262 var values =
new List<string>();
266 var row = worksheet.Row(rowNumber);
267 foreach (var cell
in row.CellsUsed())
269 values.Add(cell.GetString());
274 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to get values for row [{rowNumber}]",
null, Enums.GPALObjectType.None, ex);
289 internal static List<(
string Address,
int Row,
int Column)> SearchValue(IXLWorksheet worksheet,
string range,
string searchValue)
291 List<(
string Address,
int Row,
int Column)> retVal =
new List<(
string Address,
int Row,
int Column)>();
295 foreach (var cell
in worksheet.Range(range).CellsUsed())
296 if (cell.GetString() == searchValue)
297 retVal.Add((cell.Address.ToString(), cell.Address.RowNumber, cell.Address.ColumnNumber));
301 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to search value in range [{range}]",
null, Enums.GPALObjectType.None, ex);
307 internal static void SearchAndReplaceByValue(IXLWorksheet worksheet,
string range,
string searchValue,
string replaceValue)
311 var xlRange = worksheet.Range(range);
312 foreach (var cell
in xlRange.CellsUsed())
314 if (cell.GetString() == searchValue)
316 cell.Value = replaceValue;
322 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION, $
"Failed to search and replace in range [{range}]",
null, Enums.GPALObjectType.None, ex);
341 public static void WriteXlsxFromTokenizedData(
343 IGPALGrid<string> grid,
344 List<int> rowsPerSheet,
345 IGPALGrid<string> columnNamesPerSheet,
346 List<string> sheetNames,
347 bool writeHeaders =
true)
349 if (grid ==
null)
throw new ArgumentNullException(nameof(grid));
350 if (rowsPerSheet ==
null)
throw new ArgumentNullException(nameof(rowsPerSheet));
351 if (columnNamesPerSheet ==
null)
throw new ArgumentNullException(nameof(columnNamesPerSheet));
353 using var workbook =
new XLWorkbook();
357 if (0 == rowsPerSheet.Count && 0 < grid.Rows)
359 rowsPerSheet =
new List<int> { grid.Rows };
361 if (0 == columnNamesPerSheet.Rows)
362 columnNamesPerSheet.AddRow(
new List<string>(grid[0]));
365 int currentRowInGrid = 0;
367 for (
int sheetIdx = 0; sheetIdx < rowsPerSheet.Count; sheetIdx++)
369 int totalRowsThisSheet = rowsPerSheet[sheetIdx];
370 if (totalRowsThisSheet == 0)
continue;
372 var columnNames = columnNamesPerSheet[sheetIdx];
374 string sheetName = sheetNames !=
null && sheetIdx < sheetNames.Count
375 ? sheetNames[sheetIdx]
376 : $
"Sheet{sheetIdx + 1}";
378 var worksheet = workbook.Worksheets.Add(sheetName);
385 for (
int col = 0; col < columnNames.Count; col++)
386 worksheet.Cell(1, col + 1).Value = columnNames[col];
388 worksheet.Row(1).Style.Font.Bold =
true;
392 int startOffset = writeHeaders ? 1 : 0;
393 int dataRowsToWrite = totalRowsThisSheet - startOffset;
396 for (
int i = 0; i < dataRowsToWrite; i++)
398 var sourceRow = grid[currentRowInGrid + startOffset + i];
401 for (
int col = 0; col < columnNames.Count; col++)
403 string value = col < sourceRow.Count ? sourceRow[col] ?? string.Empty :
string.Empty;
404 worksheet.Cell(destRow, col + 1).Value = value;
411 if (columnNames.Count > 0)
412 worksheet.Columns(1, columnNames.Count).AdjustToContents();
414 currentRowInGrid += totalRowsThisSheet;
417 workbook.SaveAs(outputPath);