ExcelDynamicReader.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using ClosedXML.Excel;
  2. using ExcelORM.Models;
  3. namespace ExcelORM;
  4. public class ExcelDynamicReader
  5. {
  6. private readonly IXLWorkbook xlWorkbook;
  7. public bool SkipHidden { get; set; }
  8. public bool ObeyFilter { get; set; }
  9. public ExcelDynamicReader(string? path)
  10. {
  11. xlWorkbook = new XLWorkbook(path);
  12. }
  13. private IEnumerable<List<DynamicCell>> ProcessRows(IEnumerable<IXLRow> rows, List<DynamicCell> mapping)
  14. {
  15. foreach (var row in rows)
  16. {
  17. if (SkipHidden && row.IsHidden) continue;
  18. var dynamicRow = new List<DynamicCell>();
  19. foreach (var item in mapping)
  20. {
  21. var cell = row.Cell(item.Position);
  22. if (cell == null || cell.Value.IsBlank)
  23. {
  24. dynamicRow.Add(item);
  25. continue;
  26. }
  27. if (item.Type == null) item.Type = cell.Value.ValueType();
  28. var cellItem = item with
  29. {
  30. Value = cell.Value.ToObject()
  31. };
  32. dynamicRow.Add(cellItem);
  33. }
  34. yield return dynamicRow;
  35. }
  36. }
  37. private IEnumerable<List<DynamicCell>> Read(IXLWorksheet? worksheet, uint startFrom = 1, uint skip = 0)
  38. {
  39. if (worksheet == null) yield break;
  40. var firstRow = worksheet.Row((int)startFrom);
  41. if (firstRow.IsEmpty())
  42. firstRow = worksheet.RowsUsed().First(x => x.RowNumber() > startFrom && !x.IsEmpty());
  43. var mapping = DynamicCell.MapHeader(firstRow.CellsUsed());
  44. if (mapping == null || mapping.Count == 0) yield break;
  45. var rowsToProcess = (ObeyFilter && worksheet.AutoFilter.IsEnabled) switch
  46. {
  47. true => worksheet.AutoFilter.VisibleRows
  48. .Where(x => x.RowNumber() > firstRow.RowNumber())
  49. .Select(x => x.WorksheetRow()),
  50. false => worksheet.RowsUsed().Where(x => x.RowNumber() > firstRow.RowNumber())
  51. };
  52. rowsToProcess = rowsToProcess
  53. .Skip((int)skip);
  54. foreach (var item in ProcessRows(rowsToProcess, mapping))
  55. yield return item;
  56. }
  57. public IEnumerable<List<DynamicCell>> Read(string? worksheetName, uint startFrom = 1, uint skip = 0)
  58. {
  59. var worksheet = xlWorkbook.Worksheets.FirstOrDefault(x => x.Name.Equals(worksheetName, StringComparison.InvariantCultureIgnoreCase));
  60. if (worksheet == null) yield break;
  61. foreach (var value in Read(worksheet, startFrom, skip))
  62. yield return value;
  63. }
  64. public IEnumerable<List<DynamicCell>> Read(int worksheetIndex = 1, uint startFrom = 1, uint skip = 0)
  65. {
  66. if (worksheetIndex > xlWorkbook.Worksheets.Count) yield break;
  67. var worksheet = xlWorkbook.Worksheets.FirstOrDefault(x => x.Position == worksheetIndex);
  68. if (worksheet == null) yield break;
  69. foreach (var value in Read(worksheet, startFrom, skip))
  70. yield return value;
  71. }
  72. public IEnumerable<DynamicWorksheet> ReadAll(uint startFrom = 1, uint skip = 0)
  73. {
  74. foreach (var worksheet in xlWorkbook.Worksheets)
  75. {
  76. yield return new DynamicWorksheet
  77. {
  78. Name = worksheet.Name,
  79. Position = worksheet.Position,
  80. Cells = Read(worksheet, startFrom, skip)
  81. };
  82. }
  83. }
  84. }