/// <summary>
        ///     解析模板
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private bool ParseTemplate <T>(ExcelPackage excelPackage, out List <ImporterHeaderInfo> columnHeaders)
            where T : class
        {
            ExcelImporterAttribute excelImporterAttribute = GetImporterAttribute <T>();

            if (null == excelImporterAttribute || string.IsNullOrWhiteSpace(excelImporterAttribute.SheetName))
            {
                throw new ImportException($"导入实体{typeof(T)}未定义ExcelImporterAttribute属性");
            }

            ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[excelImporterAttribute.SheetName];

            if (null == worksheet)
            {
                throw new ImportException($"读取名称为{excelImporterAttribute.SheetName}的sheet页异常,检查sheet页是否存在");
            }

            ParseImporterHeader <T>(out columnHeaders, out var enumColumns, out var boolColumns);
            for (var i = 0; i < columnHeaders.Count; i++)
            {
                var header = worksheet.Cells[1, i + 1].Text;
                if (columnHeaders[i].ExporterHeader != null &&
                    !string.IsNullOrWhiteSpace(columnHeaders[i].ExporterHeader.Name))
                {
                    if (!header.Equals(columnHeaders[i].ExporterHeader.Name))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!header.Equals(columnHeaders[i].PropertyName))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        /// <summary>
        ///     解析数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        /// <exception cref="ArgumentException">最大允许导入条数不能超过5000条</exception>
        private IList <T> ParseData <T>(ExcelPackage excelPackage, List <ImporterHeaderInfo> columnHeaders)
            where T : class, new()
        {
            ExcelImporterAttribute excelImporterAttribute = GetImporterAttribute <T>();

            if (null == excelImporterAttribute || string.IsNullOrWhiteSpace(excelImporterAttribute.SheetName))
            {
                throw new ImportException($"导入实体{typeof(T)}未定义ExcelImporterAttribute属性");
            }

            ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[excelImporterAttribute.SheetName];

            if (null == worksheet)
            {
                throw new ImportException($"读取名称为{excelImporterAttribute.SheetName}的sheet页异常,检查sheet页是否存在");
            }

            if (excelImporterAttribute.MaxRowNumber > _maxRowNumber)
            {
                excelImporterAttribute.MaxRowNumber = _maxRowNumber;
            }

            if (worksheet.Dimension.End.Row > excelImporterAttribute.MaxRowNumber)
            {
                throw new ImportException($"最大允许导入行数不能超过{excelImporterAttribute.MaxRowNumber}行");
            }

            IList <T> importDataModels = new List <T>();
            var       propertyInfos    = new List <PropertyInfo>(typeof(T).GetProperties());

            for (var index = 2; index <= worksheet.Dimension.End.Row; index++)
            {
                bool allRowIsEmpty = AllRowIsEmpty(worksheet, index);
                if (allRowIsEmpty)
                {
                    // 整行为空,则跳过
                    continue;
                }

                var dataItem = new T();
                foreach (var propertyInfo in propertyInfos)
                {
                    var cell = worksheet.Cells[index,
                                               columnHeaders.FindIndex(a => a.PropertyName.Equals(propertyInfo.Name)) + 1];
                    switch (propertyInfo.PropertyType.BaseType?.Name.ToLower())
                    {
                    case "enum":
                        var enumDisplayNames = EnumHelper.GetDisplayNames(propertyInfo.PropertyType);
                        if (enumDisplayNames.ContainsKey(cell.Value?.ToString() ?? throw new ArgumentException()))
                        {
                            propertyInfo.SetValue(dataItem,
                                                  enumDisplayNames[cell.Value?.ToString()]);
                        }
                        else
                        {
                            throw new ImportException($"值 {cell.Value} 不存在模板下拉选项中");
                        }

                        continue;
                    }

                    SetCellValue(propertyInfo, cell, dataItem);
                }

                importDataModels.Add(dataItem);
            }