示例#1
0
        /// <summary>
        /// Gets all the records in the Excel file and converts each to <see cref="Type"/> T.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> of the record.</typeparam>
        /// <returns>An <see cref="IEnumerable{T}" /> of records.</returns>
        public IEnumerable <T> GetRecords <T>()
        {
            // Get the type of all the records
            var type = typeof(T);

            // Make sure it is mapped
            if (_configuration.Maps[type] == null)
            {
                _configuration.Maps.Add(_configuration.AutoMap(type));
            }

            // First read the header record and parse it
            ReadRow();
            ParseHeaderRecord();

            // Create the function to read the records outside the inner loop
            Delegate parseRecord;

            try {
                parseRecord = GetParseRecordFunc(type);
            } catch (Exception ex) {
                ExceptionHelper.AddExceptionDataMessage(ex, type);
                throw;
            }

            // Read each record one at a time and yield it
            while (!IsEmptyRecord())
            {
                T record;
                try {
                    _currentIndex = -1;
                    record        = (T)parseRecord.DynamicInvoke();
                    _row++;
                } catch (Exception ex) {
                    // Build the details about the error so it can be logged
                    var details = new ExcelReadErrorDetails {
                        Row       = _row + 1,                           // Show 1 based row to the user
                        Column    = _currentIndex + 1,                  // Show 1 based column to the user
                        FieldName = (from pair in _namedIndexes
                                     from index in pair.Value
                                     where index == _currentIndex
                                     select pair.Key).SingleOrDefault(),
                        FieldValue = _sheet[_row, _currentIndex].Value,
                    };

                    // Add the details to the exception
                    ExceptionHelper.AddExceptionDataMessage(ex, type, details);

                    // If we are ignoring errors, optionally call the callback and continue
                    if (_configuration.IgnoreReadingExceptions)
                    {
                        _configuration.ReadingExceptionCallback?.Invoke(ex, details);
                        _row++;
                        continue;
                    }
                    throw;
                }
                yield return(record);
            }
        }
示例#2
0
        /// <summary>
        /// Writes the list of typed records to the Excel file.
        /// </summary>
        /// <param name="records">The list of records to write.</param>
        public void WriteRecords <T>(
            IEnumerable <T> records)
            where T : class
        {
            // Get the type of all the records
            var type = typeof(T);

            // Make sure it is mapped
            if (_configuration.Maps[type] == null)
            {
                _configuration.Maps.Add(_configuration.AutoMap(type));
            }

            // Get a list of all the properties so they will be sorted properly.
            var properties = new ExcelPropertyMapCollection();

            AddProperties(properties, _configuration.Maps[type]);
            if (properties.Count == 0)
            {
                throw new ExcelWriterException($"No properties are mapped for type '{type.FullName}'.");
            }

            // Write the header
            WriteHeader(properties);

            // Write all the column styles
            WriteColumnStyles(properties);

            // Get the action method for writing the records out
            Delegate writeRecord = null;

            try {
                writeRecord = GetWriteRecordAction(type, properties);
            } catch (Exception ex) {
                ExceptionHelper.AddExceptionDataMessage(ex, type);
                throw;
            }

            // Now process each record
            foreach (var record in records)
            {
                writeRecord.DynamicInvoke(record);
                NextRecord();
            }
        }
示例#3
0
        /// <summary>
        /// Gets all the records in the Excel file and converts each to <see cref="Type"/> T.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> of the record.</typeparam>
        /// <returns>An <see cref="IEnumerable{T}" /> of records.</returns>
        public IEnumerable <T> GetRecords <T>()
        {
            // Get the type of all the records
            var type = typeof(T);

            // Make sure it is mapped
            if (_configuration.Maps[type] == null)
            {
                _configuration.Maps.Add(_configuration.AutoMap(type));
            }

            // First read the header record and parse it
            ParseHeaderRecord();

            // Create the function to read the records outside the inner loop
            Delegate parseRecord;

            try {
                parseRecord = GetParseRecordFunc(type);
            } catch (Exception ex) {
                ExceptionHelper.AddExceptionDataMessage(ex, type);
                throw;
            }

            // Read each record one at a time and yield it
            var ignoreEmptyRows = Configuration.IgnoreEmptyRows;

            while (_reader.Read())
            {
                // If we are not ignoring empty records, bail when we reach one. Otherwise we process all rows in the file.
                if (IsEmptyRecord())
                {
                    if (ignoreEmptyRows)
                    {
                        _row++;
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }

                T record;
                try {
                    _currentIndex = -1;
                    record        = (T)parseRecord.DynamicInvoke();
                    _row++;
                } catch (Exception ex) {
                    // Build the details about the error so it can be logged
                    var details = new ExcelReadErrorDetails {
                        Row       = _row + 1,                           // Show 1 based row to the user
                        Column    = _currentIndex + 1,                  // Show 1 based column to the user
                        FieldName = (from pair in _namedIndexes
                                     from index in pair.Value
                                     where index == _currentIndex
                                     select pair.Key).SingleOrDefault(),
                        FieldValue = _reader.GetValue(_currentIndex),
                    };

                    // 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, type, details);

                    // If we are ignoring errors, optionally call the callback and continue
                    if (_configuration.IgnoreReadingExceptions)
                    {
                        _configuration.ReadingExceptionCallback?.Invoke(ex, details);
                        _row++;
                        continue;
                    }
                    throw;
                }
                yield return(record);
            }
        }