VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#_Excel数据读取与写入_自定义解析封装类_支持设置标题行位置&使用excel表达式(2)

0); T t = default(T); #region 获取深度表达式更新列表 List<IExcelCellExpressDeepUpdate<T>> excelCellExpressDeepUpdateList = new List<IExcelCellExpressDeepUpdate<T>>(0); if (excelFileDescription != null) { foreach (var item in excelFileDescription.ExcelDeepUpdateList) { if (item is IExcelCellExpressDeepUpdate<T>) { excelCellExpressDeepUpdateList.Add((IExcelCellExpressDeepUpdate<T>)item); } } } #endregion #region 通过表达式映射列表读取对象T Func<List<ExcelCellFieldMapper>, T> expressMapperFunc = (excelCellFieldMapperList) => { t = new T(); foreach (var cellMapper in excelCellFieldMapperList) { string currentCellExpress = cellMapper.CellExpressRead.CellCoordinateExpress; object pValue = ExcelHelper.GetVByExpress(currentCellExpress, workbook, sheet); try { cellMapper.PropertyInfo.SetValue(t, Convert.ChangeType(pValue, cellMapper.PropertyInfo.PropertyType)); } catch (Exception) { } } return t; }; #endregion #region 执行初始表达式数据收集 //获取t的单元格映射列表 List<ExcelCellFieldMapper> cellMapperList = ExcelCellFieldMapper.GetModelFieldMapper<T>(); t = expressMapperFunc(cellMapperList); #endregion #region 执行深度更新策略收集数据 Action<IExcelCellExpressDeepUpdate<T>> actionDeepReadAction = (excelCellExpressDeepUpdate) => { //获取初始表达式映射列表 cellMapperList = ExcelCellFieldMapper.GetModelFieldMapper<T>(); //执行单元格表达式深度更新 bool isContinute = false; do { //通过深度更新策略更新初始表达式数据 foreach (var cellMapper in cellMapperList) { if (cellMapper.CellExpressRead != null) { string currentCellExpress = cellMapper.CellExpressRead.CellCoordinateExpress; currentCellExpress = excelCellExpressDeepUpdate.GetNextCellExpress(currentCellExpress); cellMapper.CellExpressRead.CellCoordinateExpress = currentCellExpress; } } t = expressMapperFunc(cellMapperList); isContinute = excelCellExpressDeepUpdate.IsContinute(t); if (isContinute) { tList.Add(t); } } while (isContinute); }; foreach (var item in excelCellExpressDeepUpdateList) { actionDeepReadAction(item); } #endregion return tList; } /// <summary> /// 获取文件首个sheet的标题位置 /// </summary> /// <typeparam name="T">T必须做了标题映射</typeparam> /// <param name="filePath"></param> /// <returns></returns> public static int FileFirstSheetTitleIndex<T>(string filePath) { int titleIndex = 0; if (File.Exists(filePath)) { try { using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook = null; try { workbook = new XSSFWorkbook(fileStream); } catch (Exception) { workbook = new HSSFWorkbook(fileStream); } string[] titleArray = ExcelTitleFieldMapper.GetModelFieldMapper<T>().Select(m => m.ExcelTitle).ToArray(); ISheet sheet = workbook.GetSheetAt(0); titleIndex = ExcelHelper.GetSheetTitleIndex(sheet, titleArray); } } catch (Exception e) { throw new Exception($"文件:{filePath}被占用!", e); } } return titleIndex; } /// <summary> /// 获取文件首个sheet的标题位置 /// </summary> /// <param name="filePath"></param> /// <param name="titleNames"></param> /// <returns></returns> public static int FileFirstSheetTitleIndex(string filePath, params string[] titleNames) { int titleIndex = 0; if (File.Exists(filePath)) { using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook = null; try { workbook = new XSSFWorkbook(fileStream); } catch (Exception) { workbook = new HSSFWorkbook(fileStream); } ISheet sheet = workbook.GetSheetAt(0); titleIndex = ExcelHelper.GetSheetTitleIndex(sheet, titleNames); } } return titleIndex; } #endregion #region 辅助方法 /// <summary> /// 根据标题名称获取标题行下标位置 /// </summary> /// <param name="sheet">要查找的sheet</param> /// <param name="titleNames">标题名称</param> /// <returns></returns> private static int GetSheetTitleIndex(ISheet sheet, params string[] titleNames) { int titleIndex = -1; if (sheet != null && titleNames != null && titleNames.Length > 0) { var rows = sheet.GetRowEnumerator(); List<ICell> cellList = null; List<string> rowValueList = null; //从第1行数据开始获取 while (rows.MoveNext()) { IRow row = (IRow)rows.Current; cellList = row.Cells; rowValueList = new List<string>(cellList.Count); foreach (var cell in cellList) { rowValueList.Add(cell.ToString()); } bool isTitle = true; foreach (var title in titleNames) { if (!rowValueList.Contains(title)) { isTitle = false; break; } } if (isTitle) { titleIndex = row.RowNum; break; } } } return titleIndex; } #endregion }
复制代码

 

  2-ExcelCellExpressReadAttribute  单元格表达式读取特性:

复制代码
/// <summary>
    /// Excel单元格-表达式读取-标记特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)]
    public class ExcelCellExpressReadAttribute : System.Attribute
    {
        /// <summary>
        /// 读取数据使用:该参数使用表达式生成数据(Excel文件中支持的表达式均可以,可以是单元格位置也可以是表达式(如:A1,B2,C1+C2...))
        /// </summary>
        public string CellCoordinateExpress { get; set; }

        /// <summary>
        /// 字符输出格式(数字和日期类型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 生成单元格表达式读取特性
        /// </summary>
        /// <param name="cellCoordinateExpress">初始单元格表达式</param>
        /// <param name="outputFormat">(可选)格式化字符串</param>
        public ExcelCellExpressReadAttribute(string cellCoordinateExpress, string outputFormat = "")
        {
            this.CellCoordinateExpress = cellCoordinateExpress;
            this.OutputFormat = outputFormat;
        }
    }
复制代码

 

  3-ExcelCellFieldMapper  单元格字段映射类

复制代码
/// <summary>
    /// 单元格字段映射类
    /// </summary>
    internal class ExcelCellFieldMapper
    {
        /// <summary>
        /// 属性信息(一个属性可以添加一个表达式读取,多个变量替换和多个坐标写入)
        /// </summary>
        public PropertyInfo PropertyInfo { get; set; }

        /// <summary>
        /// 单元格—表达式读取(单元格坐标表达式(如:A1,B2,C1+C2...横坐标使用26进制字母,纵坐标使用十进制数字))
        /// </summary>
        public ExcelCellExpressReadAttribute CellExpressRead { get; set; }

        /// <summary>
        /// 单元格—模板文件的预定义变量写入({A} {B})
        /// </summary>
        public List<ExcelCellParamWriteAttribute> CellParamWriteList { get; set; }

        /// <summary>
        /// 单元格—坐标位置写入((0,0),(1,1))
        /// </summary>
        public List<ExcelCellPointWriteAttribute> CellPointWriteList { get; set; }

        /// <summary>
        /// 获取对应关系_T属性添加了单元格映射关系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<ExcelCellFieldMapper> GetModelFieldMapper<T>()
        {
            List<ExcelCellFieldMapper> fieldMapperList = new List<ExcelCellFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            ExcelCellExpressReadAttribute cellExpress = null;
            List<ExcelCellParamWriteAttribute> cellParamWriteList = null;
            List<ExcelCellPointWriteAttribute> cellPointWriteList = null;
            foreach (var item in tPropertyInfoList)
            {
                cellExpress = item.GetCustomAttribute<ExcelCellExpressReadAttribute>();
                cellParamWriteList = item.GetCustomAttributes<ExcelCellParamWriteAttribute>().ToList();
                cellPointWriteList = item.GetCustomAttributes<ExcelCellPointWriteAttribute>().ToList();
                if (cellExpress != null || cellParamWriteList.Count > 0 || cellPointWriteList.Count > 0)
                {
                    fieldMapperList.Add(new ExcelCellFieldMapper
                    {
                        CellExpressRead = cellExpress,
                        CellParamWriteList = cellParamWriteList,
                        CellPointWriteList = cellPointWriteList,
                        PropertyInfo = item
                    });
                }
            }

            return fieldMapperList;
        }
    }
复制代码

 

  4-ExcelCellParamWriteAttribute  Excel单元格-模板参数写入-标记特性

复制代码
/// <summary>
    /// Excel单元格-模板参数写入-标记特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)]
    public class ExcelCellParamWriteAttribute : System.Attribute
    {
        /// <summary>
        /// 模板文件的预定义变量使用({A} {B})
        /// </summary>
        public string CellParamName { get; set; }

        /// <summary>
        /// 字符输出格式(数字和日期类型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        public ExcelCellParamWriteAttribute(string cellParamName, string outputFormat = "")
        {
            CellParamName = cellParamName;
            OutputFormat = outputFormat;
        }


    }
复制代码

 

  5-ExcelCellPointWriteAttribute  Excel单元格-表达式读取-标记特性

复制代码
/// <summary>
    /// Excel单元格-表达式读取-标记特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)]
    public class ExcelCellPointWriteAttribute : System.Attribute
    {
        /// <summary>
        /// 单元格位置(A3,B4...)
        /// </summary>
        public string CellPosition { get; set; }

        /// <summary>
        /// 字符输出格式(数字和日期类型需要)
        /// </summary>
        public string OutputFormat { get; set; }


        public ExcelCellPointWriteAttribute(string cellPosition, string outputFormat = null)
        {
            CellPosition = cellPosition;
            OutputFormat = outputFormat;
        }
    }
复制代码

 

  6-ExcelFileDescription  Excel文件描述类,含有深度更新策略

复制代码
public class ExcelFileDescription
    {
        public ExcelFileDescription(int titleRowIndex)
        {
            this.TitleRowIndex = titleRowIndex;
        }

        public ExcelFileDescription(IExcelDeepUpdate excelDeepUpdate)
        {
            this.ExcelDeepUpdateList = new List<IExcelDeepUpdate> { excelDeepUpdate };
        }
        public ExcelFileDescription(List<IExcelDeepUpdate> excelDeepUpdateList)
        {
            this.ExcelDeepUpdateList = excelDeepUpdateList;
        }

        /// <summary>
        /// 标题所在行位置(默认为0,没有标题填-1)
        /// </summary>
        public int TitleRowIndex { get; set; }

        /// <summary>
        /// Excel深度更新策略
        /// </summary>
        public List<IExcelDeepUpdate> ExcelDeepUpdateList { get; set; }

    }
复制代码

 

  7-ExcelTitleAttribute  Excel标题标记特性

复制代码
/// <summary>
    /// Excel标题标记特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)]
    public class ExcelTitleAttribute : System.Attribute
    {
        /// <summary>
        /// Excel行标题(标题和下标选择一个即可)
        /// </summary>
        public string RowTitle { get; set; }
        /// <summary>
        /// Excel行下标(标题和下标选择一个即可,默认值-1)
        /// </summary>
        public int RowTitleIndex { get; set; }

        /// <summary>
        /// 单元格是否要检查空数据(true为检查,为空的行数据不添加)
        /// </summary>
        public bool IsCheckContentEmpty { get; set; }

        /// <summary>
        /// 字符输出格式(数字和日期类型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 是否是公式列
        /// </summary>
        public bool IsCoordinateExpress { get; set; }

        /// <summary>
        /// 标题特性构造方法
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="isCheckEmpty">单元格是否要检查空数据</param>
        /// <param name="isCoordinateExpress">是否是公式列</param>
        /// <param name="outputFormat">是否有格式化输出要求</param>
        public ExcelTitleAttribute(string title, bool isCheckEmpty = false, bool isCoordinateExpress = false, string outputFormat = "")
        {
            RowTitle = title;
            IsCheckContentEmpty = isCheckEmpty;
            IsCoordinateExpress = isCoordinateExpress;
            OutputFormat = outputFormat;
            RowTitleIndex = -1;
        }

        public ExcelTitleAttribute(int titleIndex, bool isCheckEmpty = false, bool isCoordinateExpress = false, string outputFormat = "")
        {
            RowTitleIndex = titleIndex;
            IsCheckContentEmpty = isCheckEmpty;
            IsCoordinateExpress = isCoordinateExpress;
            OutputFormat = outputFormat;
        }
    }
复制代码

 

  8-ExcelTitleFieldMapper  标题字段映射类

复制代码
/// <summary>
    /// 标题字段映射类
    /// </summary>
    internal class ExcelTitleFieldMapper
    {
        /// <summary>
        /// 属性信息
        /// </summary>
        public PropertyInfo PropertyInfo { get; set; }
        /// <summary>
        /// 行标题
        /// </summary>
        public string ExcelTitle { get; set; }
        /// <summary>
        /// 行标题下标位置
        /// </summary>
        public int ExcelTitleIndex { get; set; }
        /// <summary>
        /// 是否要做行内容空检查
        /// </summary>
        public bool IsCheckContentEmpty { get; set; }

        /// <summary>
        /// 字符输出格式(数字和日期类型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 是否是公式列
        /// </summary>
        public bool IsCoordinateExpress { get; set; }

        /// <summary>
        /// 获取对应关系_T属性添加了标题映射关系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelFieldMapper<T>()
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            ExcelTitleAttribute excelTitleAttribute = null;
            foreach (var tPropertyInfo in tPropertyInfoList)
            {
                excelTitleAttribute = (ExcelTitleAttribute)tPropertyInfo.GetCustomAttribute(typeof(ExcelTitleAttribute));
                
                if (excelTitleAttribute != null)
                {
                    fieldMapperList.Add(new ExcelTitleFieldMapper
                    {
                        PropertyInfo = tPropertyInfo,
                        ExcelTitle = excelTitleAttribute.RowTitle,
                        ExcelTitleIndex = excelTitleAttribute.RowTitleIndex,
                        IsCheckContentEmpty = excelTitleAttribute.IsCheckContentEmpty,
                        OutputFormat = excelTitleAttribute.OutputFormat,
                        IsCoordinateExpress = excelTitleAttribute.IsCoordinateExpress
                    });
                }
            }
            return fieldMapperList;
        }

        /// <summary>
        /// 获取对应关系_手动提供映射关系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldNameAndShowNameDic"></param>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelFieldMapper<T>(Dictionary<string, string> fieldNameAndShowNameDic)
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            PropertyInfo propertyInfo = null;

            foreach (var item in fieldNameAndShowNameDic)
            {
                propertyInfo = tPropertyInfoList.Find(m => m.Name.Equals(item.Key, StringComparison.OrdinalIgnoreCase));

                fieldMapperList.Add(new ExcelTitleFieldMapper
                {
                    PropertyInfo = propertyInfo,
                    ExcelTitle = item.Value,
                    ExcelTitleIndex = -1,
                    OutputFormat = null,
                    IsCheckContentEmpty = false,
                    IsCoordinateExpress = false
                });
            }
            return fieldMapperList;
        }

        /// <summary>
        /// 获取对应关系_未提供(默认属性名和标题名一致)
        /// </summary>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelDefaultFieldMapper<T>()
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();

            foreach (var item in tPropertyInfoList)
            {
                fieldMapperList.Add(new ExcelTitleFieldMapper
                {
                    PropertyInfo = item,
                    ExcelTitle = item.Name,
                    ExcelTitleIndex = -1,
                    OutputFormat = null,
                    IsCheckContentEmpty = false,
                    IsCoordinateExpress = false
                });
            }
            return fieldMapperList;
        }

    }
复制代码

 

  接口封装类:

  a-CellFactory  单元格工厂类

复制代码
/// <summary>
    /// 单元格工厂类
    /// </summary>
    public class CellFactory
    {
        private static Regex _CellPostionRegex = new Regex("[A-Z]+\\d+");
        private static Regex _RowRegex = new Regex("\\d+");

        /// <summary>
        /// 通过Excel单元格坐标位置初始化对象
        /// </summary>
        /// <param name="excelCellPosition">A1,B2等等</param>
        /// <returns></returns>
        public static ICellModel GetCellByExcelPosition(string excelCellPosition)
        {
            CellModel cellModel = null;

            bool isMatch = CellFactory._CellPostionRegex.IsMatch(excelCellPosition);
            if (isMatch)
            {
                Match rowMath = CellFactory._RowRegex.Match(excelCellPosition);
                int rowPositon = Convert.ToInt32(rowMath.Value);
                int rowIndex = rowPositon - 1;
                int columnIndex = CellFactory.GetExcelColumnIndex(excelCellPosition.Replace(rowPositon.ToString(), ""));

                cellModel = new CellModel(rowIndex, columnIndex);
            }
            return cellModel;
        }

        /// <summary>
        /// 将数据放入单元格中
        /// </summary>
        /// <param name="cell">单元格对象</param>
        /// <param name="cellValue">数据</param>
        /// <param name="outputFormat">格式化字符串</param>
        /// <param name="isCoordinateExpress">是否是表达式数据</param>
        public static void SetCellValue(ICell cell, object cellValue, string outputFormat, bool isCoordinateExpress)
        {
            if (cell != null)
            {
                if (isCoordinateExpress)
                {
                    cell.SetCellFormula(cellValue.ToString());
                }
                else
                {
                    if (!string.IsNullOrEmpty(outputFormat))
                    {
                        string formatValue = null;
                        IFormatProvider formatProvider = null;
                        if (cellValue is DateTime)
                        {
                            formatProvider = new DateTimeFormatInfo();
                            ((DateTimeFormatInfo)formatProvider).ShortDatePattern = outputFormat;
                        }
                        formatValue = ((IFormattable)cellValue).ToString(outputFormat, formatProvider);

                        cell.SetCellValue(formatValue);
                    }
                    else
      



  

相关教程