Beispiel #1
0
        /// <summary>
        /// 从指定流加载数据到<see cref="IEnumerable{T}"/>集合
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="excelStream">流</param>
        /// <param name="excelSetting">用于加载数据的Excel设置</param>
        /// <param name="startRow">数据读取起始行</param>
        /// <param name="sheetIndex">工作表索引</param>
        /// <returns></returns>
        public static IEnumerable <T> Load <T>(Stream excelStream, ExcelSetting excelSetting, int startRow,
                                               int sheetIndex) where T : class, new()
        {
            var workbook = InitializeWorkbook(excelStream);

            var sheet = workbook.GetSheetAt(sheetIndex);

            if (null == sheet)
            {
                throw new ArgumentException($"找不到指定索引[{sheetIndex}]工作表", nameof(sheetIndex));
            }

            return(Load <T>(sheet, _formulaEvaluator, excelSetting, startRow));
        }
Beispiel #2
0
        /// <summary>
        /// 从指定流加载数据到<see cref="IEnumerable{T}"/>集合
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="excelStream">流</param>
        /// <param name="excelSetting">用于加载数据的Excel设置</param>
        /// <param name="sheetName">工作表名称</param>
        /// <param name="startRow">数据读取起始行</param>
        /// <returns></returns>
        public static IEnumerable <T> Load <T>(Stream excelStream, ExcelSetting excelSetting, string sheetName,
                                               int startRow = 1) where T : class, new()
        {
            if (string.IsNullOrWhiteSpace(sheetName))
            {
                throw new ArgumentException("工作表名称不能为null或者是空字符", nameof(sheetName));
            }
            var workbook = InitializeWorkbook(excelStream);

            var sheet = workbook.GetSheet(sheetName);

            if (null == sheet)
            {
                throw new ArgumentException($"找不到指定名称[{sheetName}]工作表", nameof(sheetName));
            }

            return(Load <T>(sheet, _formulaEvaluator, excelSetting, startRow));
        }
Beispiel #3
0
        /// <summary>
        /// get a excel workbook
        /// </summary>
        /// <param name="isXlsx">is for *.xlsx file</param>
        /// <param name="excelSetting">excelSettings</param>
        /// <returns></returns>
        public static IWorkbook PrepareWorkbook(bool isXlsx, ExcelSetting excelSetting)
        {
            var setting = (excelSetting ?? DefaultExcelSetting) ?? new ExcelSetting();

            if (isXlsx)
            {
                var workbook = new XSSFWorkbook();
                var props    = workbook.GetProperties();
                props.CoreProperties.Creator     = setting.Author;
                props.CoreProperties.Created     = DateTime.Now;
                props.CoreProperties.Modified    = DateTime.Now;
                props.CoreProperties.Title       = setting.Title;
                props.CoreProperties.Subject     = setting.Subject;
                props.CoreProperties.Category    = setting.Category;
                props.CoreProperties.Description = setting.Description;
                props.ExtendedProperties.GetUnderlyingProperties().Company     = setting.Company;
                props.ExtendedProperties.GetUnderlyingProperties().Application = InternalConstants.ApplicationName;
                props.ExtendedProperties.GetUnderlyingProperties().AppVersion  = Version.ToString();
                return(workbook);
            }
            else
            {
                var workbook = new HSSFWorkbook();
                ////create a entry of DocumentSummaryInformation
                var dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company  = setting.Company;
                dsi.Category = setting.Category;
                workbook.DocumentSummaryInformation = dsi;
                ////create a entry of SummaryInformation
                var si = PropertySetFactory.CreateSummaryInformation();
                si.Title                    = setting.Title;
                si.Subject                  = setting.Subject;
                si.Author                   = setting.Author;
                si.CreateDateTime           = DateTime.Now;
                si.Comments                 = setting.Description;
                si.ApplicationName          = InternalConstants.ApplicationName;
                workbook.SummaryInformation = si;
                return(workbook);
            }
        }
Beispiel #4
0
 /// <summary>
 /// prepare a workbook for export
 /// </summary>
 /// <param name="excelFormat">excelFormat</param>
 /// <param name="excelSetting">excelSetting</param>
 /// <returns></returns>
 public static IWorkbook PrepareWorkbook(ExcelFormat excelFormat, ExcelSetting excelSetting)
 {
     return(PrepareWorkbook(excelFormat == ExcelFormat.Xlsx, excelSetting));
 }
Beispiel #5
0
        /// <summary>
        ///     DataTable2ExcelBytes
        /// </summary>
        /// <param name="dataTable">dataTable</param>
        /// <param name="excelFormat">excelFormat</param>
        /// <param name="excelSetting">excelSetting</param>
        public static byte[] ToExcelBytes([NotNull] this DataTable dataTable, ExcelFormat excelFormat, ExcelSetting excelSetting)
        {
            var workbook = ExcelHelper.PrepareWorkbook(excelFormat, excelSetting);
            var sheet = workbook.CreateSheet(
                string.IsNullOrWhiteSpace(dataTable.TableName)
                ? "Sheet0"
                : dataTable.TableName);
            var headerRow = sheet.CreateRow(0);
            for (var i = 0; i < dataTable.Columns.Count; i++)
            {
                headerRow.CreateCell(i, CellType.String)
                    .SetCellValue(dataTable.Columns[i].ColumnName);
            }

            for (var i = 1; i <= dataTable.Rows.Count; i++)
            {
                var row = sheet.CreateRow(i);
                for (var j = 0; j < dataTable.Columns.Count; j++)
                {
                    row.CreateCell(j, CellType.String)
                        .SetCellValue(dataTable.Rows[i - 1][j]);
                }
            }

            return workbook.ToExcelBytes();
        }
Beispiel #6
0
 /// <summary>
 ///     export DataTable to excel file
 /// </summary>
 /// <param name="dataTable">dataTable</param>
 /// <param name="excelPath">excelPath</param>
 /// <param name="excelSetting">excelSetting</param>
 /// <returns></returns>
 public static void ToExcelFile([NotNull] this DataTable dataTable, [NotNull] string excelPath, ExcelSetting excelSetting)
 {
     var workbook = ExcelHelper.PrepareWorkbook(excelPath, excelSetting);
     var sheet = workbook.CreateSheet(
         string.IsNullOrWhiteSpace(dataTable.TableName)
         ? "Sheet0"
         : dataTable.TableName);
     if (dataTable.Columns.Count > 0)
     {
         var headerRow = sheet.CreateRow(0);
         for (var i = 0; i < dataTable.Columns.Count; i++)
         {
             headerRow.CreateCell(i, CellType.String).SetCellValue(dataTable.Columns[i].ColumnName);
         }
         for (var i = 1; i <= dataTable.Rows.Count; i++)
         {
             var row = sheet.CreateRow(i);
             for (var j = 0; j < dataTable.Columns.Count; j++)
             {
                 row.CreateCell(j, CellType.String).SetCellValue(dataTable.Rows[i - 1][j]);
             }
         }
     }
     workbook.WriteToFile(excelPath);
 }
Beispiel #7
0
        /// <summary>
        ///     DataTable2ExcelBytes
        /// </summary>
        /// <param name="dataTable">dataTable</param>
        /// <param name="excelFormat">excelFormat</param>
        /// <param name="excelSetting">excelSetting</param>
        public static byte[] ToExcelBytes([NotNull] this DataTable dataTable, ExcelFormat excelFormat, ExcelSetting excelSetting)
        {
            var workbook = dataTable.GetWorkbookWithAutoSplitSheet(excelFormat, excelSetting);

            return(workbook.ToExcelBytes());
        }
Beispiel #8
0
        /// <summary>
        ///     DataTable2ExcelStream
        /// </summary>
        /// <param name="dataTable">dataTable</param>
        /// <param name="stream">stream</param>
        /// <param name="excelFormat">excelFormat</param>
        /// <param name="excelSetting">excelSetting</param>
        /// <returns></returns>
        public static void ToExcelStream([NotNull] this DataTable dataTable, [NotNull] Stream stream, ExcelFormat excelFormat, ExcelSetting excelSetting)
        {
            var workbook = dataTable.GetWorkbookWithAutoSplitSheet(excelFormat, excelSetting);

            workbook.Write(stream);
        }
Beispiel #9
0
        /// <summary>
        ///     export DataTable to excel file
        /// </summary>
        /// <param name="dataTable">dataTable</param>
        /// <param name="excelPath">excelPath</param>
        /// <param name="excelSetting">excelSetting</param>
        /// <returns></returns>
        public static void ToExcelFile([NotNull] this DataTable dataTable, [NotNull] string excelPath, ExcelSetting excelSetting)
        {
            var workbook = dataTable.GetWorkbookWithAutoSplitSheet(excelPath.EndsWith("xls") ? ExcelFormat.Xls : ExcelFormat.Xlsx, excelSetting);

            workbook.WriteToFile(excelPath);
        }
Beispiel #10
0
        /// <summary>
        /// GetWorkbookWithAutoSplitSheet
        /// </summary>
        /// <param name="dataTable">dataTable</param>
        /// <param name="excelFormat">excel format</param>
        /// <param name="excelSetting">excelSetting</param>
        /// <returns>excel workbook with data</returns>
        public static IWorkbook GetWorkbookWithAutoSplitSheet(this DataTable dataTable, ExcelFormat excelFormat, ExcelSetting excelSetting = null)
        {
            var workbook    = ExcelHelper.PrepareWorkbook(excelFormat, excelSetting ?? ExcelHelper.DefaultExcelSetting);
            var maxRowCount = excelFormat == ExcelFormat.Xls
                ? InternalConstants.MaxRowCountXls
                : InternalConstants.MaxRowCountXlsx;

            maxRowCount -= 1;

            var sheetCount = (dataTable.Rows.Count + maxRowCount - 1) / maxRowCount;

            do
            {
                workbook.CreateSheet();
            } while (workbook.NumberOfSheets < sheetCount);

            if (dataTable.Rows.Count > maxRowCount)
            {
                for (var sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++)
                {
                    var dt = new DataTable();
                    foreach (DataColumn col in dataTable.Columns)
                    {
                        dt.Columns.Add(new DataColumn(col.ColumnName, col.DataType));
                    }
                    for (var i = 0; i < maxRowCount; i++)
                    {
                        var rowIndex = sheetIndex * maxRowCount + i;
                        if (rowIndex >= dataTable.Rows.Count)
                        {
                            break;
                        }
                        var row = dt.NewRow();
                        row.ItemArray = dataTable.Rows[rowIndex].ItemArray;
                        dt.Rows.Add(row);
                    }
                    workbook.GetSheetAt(sheetIndex).ImportData(dt);
                }
            }
            else
            {
                workbook.GetSheetAt(0).ImportData(dataTable);
            }

            return(workbook);
        }
Beispiel #11
0
 public Excel(string fullpath, ILogger logger) : base(fullpath, logger)
 {
     excel   = new MsExcel.Application();
     Setting = new ExcelSetting();
 }
Beispiel #12
0
 public SettingData()
 {
     PartReplaceExcelUploadSetting = new ExcelSetting();
     PartSpecExcelUploadSetting = new ExcelSetting();
     OrderExcelUploadSetting = new ExcelSetting();
     SalesExcelUploadSetting = new ExcelSetting();
     CycleCountExcelUploadSetting = new ExcelSetting();
     SaleVehicleExcelUploadSetting = new VehicleSaleExcelSetting();
     BonusSetting = new BonusExcelSetting();
     WarrantyPartSetting = new WarrantySetting();
     OrderDateControl = string.Empty;
     BankPaymentSettings = new List<BankPaymentExcelSetting>();
 }
Beispiel #13
0
        public static byte[] ToExcel <T>(this IEnumerable <T> source, string excelFile, ExcelSetting excelSetting,
                                         Expression <Func <T, string> > sheetSelecor, int maxRowsPersheet = int.MaxValue, bool overwrite = false)
            where T : class
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            bool isVolatile = string.IsNullOrWhiteSpace(excelFile);

            if (!isVolatile)
            {
                var extension = Path.GetExtension(excelFile);
                if (extension.Equals(".xls", StringComparison.InvariantCultureIgnoreCase))
                {
                    excelSetting.UseXlsx = false;
                }
                else if (extension.Equals(".xlsx", StringComparison.InvariantCultureIgnoreCase))
                {
                    excelSetting.UseXlsx = true;
                }
                else
                {
                    throw new NotSupportedException($"不是Excel文件(*.xls|*.xlsx) 扩展名:{extension}");
                }
            }
            else
            {
                excelFile = null;
            }

            IWorkbook workbook = InitializeWorkbook(excelFile, excelSetting);

            using (Stream ms = isVolatile?(Stream) new MemoryStream():new FileStream(excelFile, FileMode.OpenOrCreate, FileAccess.Write))
            {
                IEnumerable <byte> output = Enumerable.Empty <byte>();
                foreach (var sheet in source.AsQueryable().GroupBy(sheetSelecor))
                {
                    int sheetIndex = 0;
                    var content    = sheet.Select(row => row);
                    while (content.Any())
                    {
                        workbook = content.Take(maxRowsPersheet).ToWorkbook(workbook,
                                                                            sheet.Key + (sheetIndex > 0 ? "_" + sheetIndex.ToString() : ""), overwrite);
                        sheetIndex++;
                        content = content.Skip(maxRowsPersheet);
                    }
                }
                workbook.Write(ms);
                return(isVolatile ? ((MemoryStream)ms).ToArray() : null);
            }
        }
Beispiel #14
0
        public static IWorkbook ToWorkbook <T>(this IEnumerable <T> source, IWorkbook workbook, ExcelSetting excelSetting,
                                               string sheetName = "sheet0", bool overwrite = false) where T : class
        {
            if (null == source)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (null == workbook)
            {
                throw new ArgumentNullException(nameof(workbook));
            }
            if (string.IsNullOrWhiteSpace(sheetName))
            {
                throw new ArgumentNullException($"工作表名称不能为空或空字符串", nameof(sheetName));
            }

            var properties =
                typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);

            bool fluentConfigEnabled = false;

            if (excelSetting.FluentConfigs.TryGetValue(typeof(T), out var fluentConfig))
            {
                fluentConfigEnabled = true;
                (fluentConfig as FluentConfiguration <T>)?.AdjustAutoIndex();
            }

            // 查找输出配置
            var propertyConfigurations = new PropertyConfiguration[properties.Length];

            for (var i = 0; i < properties.Length; i++)
            {
                var property = properties[i];
                if (fluentConfigEnabled && fluentConfig.PropertyConfigurations.TryGetValue(property.Name, out var pc))
                {
                    propertyConfigurations[i] = pc;
                }
                else
                {
                    propertyConfigurations[i] = null;
                }
            }

            // 再次检查工作表名称
            var sheet = workbook.GetSheet(sheetName);

            if (sheet == null)
            {
                sheet = workbook.CreateSheet(sheetName);
            }
            else
            {
                // 如果不需要,则不会覆盖现有工作表
                if (!overwrite)
                {
                    sheet = workbook.CreateSheet();
                }
            }

            // 缓存单元格样式
            var cellStyles = new Dictionary <int, ICellStyle>();

            // 标题行单元格样式
            ICellStyle titleStyle = null;

            if (excelSetting.TitleCellStyleApplier != null)
            {
                var style = new CellStyle();
                excelSetting.TitleCellStyleApplier(style);
                titleStyle = CellStyleResolver.Resolve(workbook, style);
            }

            var titleRow = sheet.CreateRow(0);
            var rowIndex = 1;

            foreach (var item in source)
            {
                var row = sheet.CreateRow(rowIndex);
                for (var i = 0; i < properties.Length; i++)
                {
                    var property = properties[i];

                    int index  = i;
                    var config = propertyConfigurations[i];
                    if (config != null)
                    {
                        if (config.IgnoreExport)
                        {
                            continue;
                        }

                        index = config.Index;
                        if (index < 0)
                        {
                            throw new Exception($"{property.Name} 索引值不能小于0。请参考 HasExcelIndex(int index) 方法以获取更多信息。");
                        }
                    }

                    if (rowIndex == 1)
                    {
                        // 没有标题的时候,使用属性名作为标题
                        var title = property.Name;
                        if (!string.IsNullOrWhiteSpace(config?.Title))
                        {
                            title = config.Title;
                        }

                        if (!string.IsNullOrWhiteSpace(config?.Formatter))
                        {
                            try
                            {
                                var style      = workbook.CreateCellStyle();
                                var dataFormat = workbook.CreateDataFormat();
                                style.DataFormat = dataFormat.GetFormat(config.Formatter);
                                cellStyles[i]    = style;
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Debug.WriteLine(e.ToString());
                            }
                        }

                        var titleCell = titleRow.CreateCell(index);
                        if (titleCell != null)
                        {
                            titleCell.CellStyle = titleStyle;
                        }
                        titleCell.SetValue(title);
                    }

                    var unwrapType = property.PropertyType.UnwrapNullableType();
                    var value      = property.GetValue(item, null);
                    // 进行值转换
                    if (config?.CellValueConverter != null)
                    {
                        value = config.CellValueConverter(rowIndex, index, value);
                        if (value == null)
                        {
                            continue;
                        }
                        unwrapType = value.GetType().UnwrapNullableType();
                    }

                    if (value == null)
                    {
                        continue;
                    }

                    var cell = row.CreateCell(index);
                    if (cellStyles.TryGetValue(i, out var cellStyle))
                    {
                        cell.CellStyle = cellStyle;
                    }
                    else if (!string.IsNullOrWhiteSpace(config?.Formatter) && value is IFormattable fv)
                    {
                        // C#格式化程序
                        cell.SetCellValue(fv.ToString(config.Formatter, CultureInfo.CurrentCulture));
                        continue;
                    }

                    cell.SetValue(value);
                }

                rowIndex++;
            }

            // 合并单元格
            var mergableConfigs = propertyConfigurations.Where(c => c != null && c.AllowMerge).ToList();

            if (mergableConfigs.Any())
            {
                var vStyle = workbook.CreateCellStyle();
                vStyle.VerticalAlignment = VerticalAlignment.Center;

                foreach (var config in mergableConfigs)
                {
                    object previous = null;
                    int    rowSpan = 0, row = 1;
                    for (row = 1; row < rowIndex; row++)
                    {
                        var value = sheet.GetRow(row).GetCellValue(config.Index, _formulaEvaluator);
                        if (object.Equals(previous, value) && value != null)
                        {
                            rowSpan++;
                        }
                        else
                        {
                            if (rowSpan > 1)
                            {
                                sheet.GetRow(row - rowSpan).Cells[config.Index].CellStyle = vStyle;
                                sheet.AddMergedRegion(new CellRangeAddress(row - rowSpan, row - 1, config.Index,
                                                                           config.Index));
                            }

                            rowSpan  = 1;
                            previous = value;
                        }
                    }

                    if (rowSpan > 1)
                    {
                        sheet.GetRow(row - rowSpan).Cells[config.Index].CellStyle = vStyle;
                        sheet.AddMergedRegion(new CellRangeAddress(row - rowSpan, row - 1, config.Index, config.Index));
                    }
                }
            }

            if (rowIndex > 1 && fluentConfigEnabled)
            {
                var statistics    = fluentConfig.StatisticsConfigurations;
                var filterConfigs = fluentConfig.FilterConfigurations;
                var freezeConfigs = fluentConfig.FreezeConfigurations;

                // 统计信息
                foreach (var item in statistics)
                {
                    var lastRow = sheet.CreateRow(rowIndex);
                    var cell    = lastRow.CreateCell(0);
                    cell.SetValue(item.Name);
                    foreach (var column in item.Columns)
                    {
                        cell             = lastRow.CreateCell(column);
                        cell.CellStyle   = sheet.GetRow(rowIndex - 1)?.GetCell(column)?.CellStyle;
                        cell.CellFormula =
                            $"{item.Formula}({GetCellPosition(1, column)}:{GetCellPosition(rowIndex - 1, column)})";
                    }
                    rowIndex++;
                }

                // 冻结窗口
                foreach (var freeze in freezeConfigs)
                {
                    sheet.CreateFreezePane(freeze.ColumnSplit, freeze.RowSpit, freeze.LeftMostColumn, freeze.TopRow);
                }

                // 筛选器
                foreach (var filter in filterConfigs)
                {
                    sheet.SetAutoFilter(new CellRangeAddress(filter.FirstRow, filter.LastRow ?? rowIndex,
                                                             filter.FirstColumn, filter.LastColumn));
                }
            }

            // 自动列宽
            if (excelSetting.AutoSizeColumnsEnabled)
            {
                for (var i = 0; i < properties.Length; i++)
                {
                    sheet.AutoSizeColumn(i);
                }
            }

            return(workbook);
        }
Beispiel #15
0
 public static IWorkbook ToWorkbook <T>(this IEnumerable <T> source, ExcelSetting excelSetting,
                                        string sheetName = "sheet0") where T : class => ToWorkbook <T>(source,
                                                                                                       InitializeWorkbook(null, excelSetting), excelSetting, sheetName, false);
Beispiel #16
0
        /// <summary>
        /// 从指定工作表加载数据到<see cref="IEnumerable{T}"/>集合
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="sheet">工作表</param>
        /// <param name="formulaEvaluator">计算公式</param>
        /// <param name="excelSetting">用于加载数据的Excel设置</param>
        /// <param name="startRow">数据读取起始行</param>
        /// <returns></returns>
        public static IEnumerable <T> Load <T>(ISheet sheet, IFormulaEvaluator formulaEvaluator,
                                               ExcelSetting excelSetting, int startRow = 1) where T : class, new()
        {
            if (sheet == null)
            {
                throw new ArgumentNullException(nameof(sheet));
            }

            var properties =
                typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);

            bool fluentConfigEnabled = excelSetting.FluentConfigs.TryGetValue(typeof(T), out var fluentConfig);

            var propertyConfigurations = new PropertyConfiguration[properties.Length];

            for (var j = 0; j < properties.Length; j++)
            {
                var property = properties[j];
                if (fluentConfigEnabled && fluentConfig.PropertyConfigurations.TryGetValue(property.Name, out var pc))
                {
                    propertyConfigurations[j] = pc;
                }
                else
                {
                    propertyConfigurations[j] = null;
                }
            }

            var statistics = new List <StatisticsConfiguration>();

            if (fluentConfigEnabled)
            {
                statistics.AddRange(fluentConfig.StatisticsConfigurations);
            }

            var list = new List <T>();
            int idx  = 0;

            IRow headerRow = null;

            var rows = sheet.GetRowEnumerator();

            while (rows.MoveNext())
            {
                var row = rows.Current as IRow;
                if (idx == 0)
                {
                    headerRow = row;
                }
                idx++;

                if (row.RowNum < startRow)
                {
                    continue;
                }

                if (true == fluentConfig?.IgnoreWitespaceRows)
                {
                    if (row.Cells.All(x =>
                                      CellType.Blank == x.CellType || (CellType.String == x.CellType &&
                                                                       string.IsNullOrWhiteSpace(x.StringCellValue))))
                    {
                        continue;
                    }
                }

                var item        = new T();
                var itemIsValid = true;
                for (var i = 0; i < properties.Length; i++)
                {
                    var prop   = properties[i];
                    int index  = i;
                    var config = propertyConfigurations[i];
                    if (config != null)
                    {
                        if (config.IgnoreImport)
                        {
                            continue;
                        }
                        index = config.Index;

                        // 自动发现索引
                        if (index < 0 && config.AutoIndex && !string.IsNullOrWhiteSpace(config.Title))
                        {
                            foreach (var cell in headerRow.Cells)
                            {
                                if (!string.IsNullOrWhiteSpace(cell.StringCellValue))
                                {
                                    if (cell.StringCellValue.Equals(config.Title,
                                                                    StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        index = cell.ColumnIndex;
                                        // 缓存单元格索引
                                        config.Index = index;
                                        break;
                                    }
                                }
                            }
                        }

                        // 再次检查索引是否设置
                        if (index < 0)
                        {
                            throw new ApplicationException("请设置'Index'或'AutoIndex'");
                        }
                    }

                    object value = row.GetCellValue(index, formulaEvaluator);
                    // 进行值校验
                    if (null != config?.CellValueValidator)
                    {
                        var validationResult = config.CellValueValidator(row.RowNum - 1, config.Index, value);
                        if (false == validationResult)
                        {
                            if (fluentConfig.SkipInvalidRows)
                            {
                                itemIsValid = false;
                                break;
                            }

                            throw new ArgumentException(
                                      $"行 {row.RowNum} , 列 {config.Title}({config.Index + 1})中单元格值校验失败!值:[{value}]");
                        }
                    }

                    // 进行值转换
                    if (config?.CellValueConverter != null)
                    {
                        value = config.CellValueConverter(row.RowNum - 1, config.Index, value);
                    }

                    if (value == null)
                    {
                        continue;
                    }

                    // 检查是否统计行
                    if (idx > startRow + 1 && index == 0 && statistics.Any(x =>
                                                                           x.Name.Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase)))
                    {
                        var st = statistics.FirstOrDefault(x =>
                                                           x.Name.Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase));
                        var formula = row.GetCellValue(st.Columns.First()).ToString();
                        if (formula.StartsWith(st.Formula, StringComparison.InvariantCultureIgnoreCase))
                        {
                            itemIsValid = false;
                            break;
                        }
                    }

                    // 属性类型
                    var propType  = prop.PropertyType.UnwrapNullableType();
                    var safeValue = Convert.ChangeType(value, propType, CultureInfo.CurrentCulture);
                    prop.SetValue(item, safeValue, null);
                }

                if (itemIsValid)
                {
                    // 进行行数据校验
                    if (null != fluentConfig?.RowDataValidator)
                    {
                        var validationResult = fluentConfig.RowDataValidator(row.RowNum - 1, item);
                        if (false == validationResult)
                        {
                            if (fluentConfig.SkipInvalidRows)
                            {
                                itemIsValid = false;
                                continue;
                            }
                            throw new ArgumentException($"行数据 {row.RowNum} 校验失败");
                        }
                    }

                    list.Add(item);
                }
            }

            return(list);
        }