码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2019-02-11 13:00:00      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:公式   文件   class   日期类   取值   tostring   code   stat   form   

项目中经常会遇到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

 

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

标签:公式   文件   class   日期类   取值   tostring   code   stat   form   

原文地址:https://www.cnblogs.com/linJie1930906722/p/10361299.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!