• .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable


    项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示

    读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示:

    合并单元格的值填充,这种格式的datatable使用SqlBulkCopy批量导入更为方便

    Excel转datatable方法代码:

            /// <summary>
            /// Excel转DataTable
            /// </summary>
            /// <param name="filePath">excel文件路径</param>
            /// <returns></returns>
            public static DataTable ExcelToDataTable(string filePath)
            {
                DataTable dt = new DataTable();
                using (FileStream fsRead = System.IO.File.OpenRead(filePath))
                {
                    IWorkbook wk = null;
                    //获取后缀名
                    string extension = filePath.Substring(filePath.LastIndexOf(".")).ToString().ToLower();
                    //判断是否是excel文件
                    if (extension == ".xlsx" || extension == ".xls")
                    {
                        //判断excel的版本
                        if (extension == ".xlsx")
                        {
                            wk = new XSSFWorkbook(fsRead);
                        }
                        else
                        {
                            wk = new HSSFWorkbook(fsRead);
                        }
    
                        //获取第一个sheet
                        ISheet sheet = wk.GetSheetAt(0);
                        //获取第一行
                        IRow headrow = sheet.GetRow(0);
                        //创建列
                        for (int i = headrow.FirstCellNum; i < headrow.Cells.Count; i++)
                        {
                            ICell cell = headrow.GetCell(i);
                            dt.Columns.Add(cell.ToString());
                        }
                        //读取每行,从第二行起
                        for (int r = 1; r <= sheet.LastRowNum; r++)
                        {
                            bool result = false;
                            DataRow dr = dt.NewRow();
                            //获取当前行
                            IRow row = sheet.GetRow(r);
    
                            //读取每列
                            for (int j = 0; j < row.Cells.Count; j++)
                            {
                                ICell cell = row.GetCell(j); //一个单元格
    
                                if (cell.IsMergedCell && r>1)  //检测列的单元格是否合并
                                {
                                    dr[j] = dt.Rows[r-2][j];
                                }
                                else
                                {
                                    dr[j] = GetCellValue(cell); //获取单元格的值
    
                                    if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j>0)
                                    {
                                        dr[j] = dr[j - 1];
                                    }
                                }
                                
                                                            
                                if (dr[j].ToString() != "")//全为空则不取
                                {
                                    result = true;
                                }
                            }
                            if (result == true)
                            {
                                dt.Rows.Add(dr); //把每行追加到DataTable
                            }
                        }
                    }
    
                }
                return dt;
            }
    
            #region 对单元格进行判断取值
            /// <summary>
            /// 对单元格进行判断取值
            /// </summary>
            /// <param name="cell"></param>
            /// <returns></returns>
            private static string GetCellValue(ICell cell)
            {
                if (cell == null)
                    return string.Empty;
                switch (cell.CellType)
                {
                    case CellType.Blank: //空数据类型 这里类型注意一下,不同版本NPOI大小写可能不一样,有的版本是Blank(首字母大写)
                        return string.Empty;
                    case CellType.Boolean: //bool类型
                        return cell.BooleanCellValue.ToString();
                    case CellType.Error:
                        return cell.ErrorCellValue.ToString();
                    case CellType.Numeric: //数字类型
                        if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
                        {
                            return cell.DateCellValue.ToString();
                        }
                        else //其它数字
                        {
                            return cell.NumericCellValue.ToString();
                        }
                    case CellType.Unknown: //无法识别类型
                    default: //默认类型
                        return cell.ToString();//
                    case CellType.String: //string 类型
                        {
                            if (cell.IsMergedCell)
                            {
                               
                            }
                            return cell.StringCellValue;
                        }
    
                    case CellType.Formula: //带公式类型
                        try
                        {
                            HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(cell.Sheet.Workbook);
                            e.EvaluateInCell(cell);
                            return cell.ToString();
                        }
                        catch
                        {
                            return cell.NumericCellValue.ToString();
                        }
                }
            }
            #endregion

    demo下载链接: https://pan.baidu.com/s/19xjsljfWe_ezffmjKDSwVg 提取码: udgh

  • 相关阅读:
    Delphi XE5 图解为Android应用制作签名
    Delphi事件的广播 转
    Delphi XE6 Android拨号函数
    Firemonkey里触发home按键被按下的事件
    如何处理App的Application的事件
    SQL SERVER存储过程中使用事务与捕获异常
    关于蓝牙打印机的开发
    图标大全网站
    提高Android和iOS调试编译速度
    百万级数据查询优化(数据库)
  • 原文地址:https://www.cnblogs.com/linJie1930906722/p/10361299.html
Copyright © 2020-2023  润新知