/// <summary> /// Parses the named indexes from the header record. /// </summary> private void ParseHeaderRecord() { // We assume all columns contain headers by default _columnCount = _sheet.Columns.Count; // First make sure we have a header record if (IsEmptyRecord()) { throw new ExcelReaderException("No header record was found."); } // Process each column in the header row for (var i = 0; i < _columnCount; i++) { // Get the header name var name = _sheet[_row, i].Value as string; if (string.IsNullOrWhiteSpace(name)) { // Header is null or empty, so we are done. This can happen if the file has more total columns // in it than header rows, which can happen if some white space ends up in a right column // or there are extra rows below the records. Also check that the next column is // also empty and throw and exception if not. if (i + 1 < _columnCount && !string.IsNullOrWhiteSpace(_sheet[_row, i + 1].Value as string)) { throw new Exception($"Blank column header found at column {ColumnHelper.ColumnIndexToColumnLetter(i + 1)}"); } _columnCount = i; break; } // Now store the named index for later for this header column if (!_configuration.IsHeaderCaseSensitive) { name = name.ToLower(); } if (_namedIndexes.ContainsKey(name)) { _namedIndexes[name].Add(i); } else { _namedIndexes[name] = new List <int> { i }; } } // Move to the next row _row++; }
/// <summary> /// Gets all the records in the Excel file and converts each to dictionary of strings to strings. /// </summary> /// <returns>An enumeration of dictionaries.</returns> public IEnumerable <Dictionary <string, string> > GetRecordsAsDictionary() { // We assume all columns contain headers by default _columnCount = _sheet.Columns.Count; // First make sure we have a header record ReadRow(); if (IsEmptyRecord()) { throw new ExcelReaderException("No header record was found."); } // Process each column in the header row var headers = new List <string>(); for (var i = 0; i < _columnCount; i++) { // Get the header name var name = _sheet[_row, i].Value as string; if (string.IsNullOrWhiteSpace(name)) { // Header is null or empty, so we are done. This can happen if the file has more total columns // in it than header rows, which can happen if some white space ends up in a right column // or there are extra rows below the records. Also check that the next column is // also empty and throw and exception if not. if (i + 1 < _columnCount && !string.IsNullOrWhiteSpace(_sheet[_row, i + 1].Value as string)) { throw new Exception($"Blank column header found at column {ColumnHelper.ColumnIndexToColumnLetter(i + 1)}"); } _columnCount = i; break; } // Now store the named index for later for this header column if (!_configuration.IsHeaderCaseSensitive) { name = name.ToLower(); } headers.Add(name.Trim()); } // Move to the next row _row++; // Read each record one at a time and yield it while (!IsEmptyRecord()) { var record = new Dictionary <string, string>(); for (var i = 0; i < _columnCount; i++) { try { var cell = _sheet[_row, i]; record.Add(headers[i], FormatValueAsString(cell, _row, i, true)); } catch (Exception ex) { // Build the details about the error so it can be logged var details = new ExcelReadErrorDetails { Row = _row + 1, Column = i + 1, FieldName = headers[i], FieldValue = _sheet[_row, i].Value, }; // Use the inner exception if we have one so the message is more clear ex = ex.InnerException ?? ex; // Add the details to the exception ExceptionHelper.AddExceptionDataMessage(ex, null, details); // If we are ignoring errors, optionally call the callback and continue if (_configuration.IgnoreReadingExceptions) { _configuration.ReadingExceptionCallback?.Invoke(ex, details); _row++; continue; } throw; } } _row++; yield return(record); } }