C# 使用 NPOI 处理Excel导入单元格内容是公式问题

C# 使用 NPOI 处理Excel导入单元格内容是公式问题

引言:今天在处理业务的时候,碰到导入Excel数据不成功的问题,那么就在这里做下笔记吧。
首先,我们有以下的数据。整块业务逻辑的代码在最后会贴上!
1.数值公式示例:
可以看出L3的内容值是80,公式J3*0.2
在这里插入图片描述
我们需要使用判断ICell对象的CellType枚举类型,当=CellType.Formula,则代表单元格是公式类型的。则直接用cell.NumericCellValue取值即可。
在这里插入图片描述
对于Excel来讲,除了数值的一些公式以外,还会有日期公式,不过最后都是进入到CellType.Formula判断中,需要另外根据转换出来的数值进行转换成日期类型即可。
2.日期公式示例:
G4的内容我使用的是TODAY公式获取当前日期。
在这里插入图片描述
同样的,我们需要使用判断ICell对象的CellType枚举类型,当=CellType.Formula,则代表单元格是公式类型的。则直接用cell.NumericCellValue取值,需要根据取出来的数值进行转换成日期类型即可。
在这里插入图片描述
数值转换成日期的处理代码:

long isNumberDateTime = 0;
if (Int64.TryParse(cellVal.ToString(), out isNumberDateTime))
{
    //数值型,则转换成日期
    DateTime d = DateTime.FromOADate(double.Parse(cellVal.ToString()));
}

转换后的结果:
在这里插入图片描述
3.整块业务逻辑的代码:

#region Excel
        /// <summary>
        /// Excel文件转换成DataTable
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="isUseNewColumnName">是否使用新列名,默认:是</param>
        /// <param name="deleteEndRowIndex">删除上面的行索引(由于有些Excel导入时上面会存在多余行)</param>
        /// <returns>返回列名Cols0,Cols1,Cols2···以此类推</returns>
        public DataTable ExcelToTable(string filePath, bool isUseNewColumnName = true, int deleteEndRowIndex = 0)
        {
            DataTable dataTable = new DataTable();
            string a = Path.GetExtension(filePath).ToLower();
            DataTable result;
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                IWorkbook workbook;
                if (a == ".xlsx")
                {
                    workbook = new XSSFWorkbook(fileStream);
                }
                else
                {
                    if (a == ".xls")
                    {
                        workbook = new HSSFWorkbook(fileStream);
                    }
                    else
                    {
                        workbook = null;
                        throw new Exception("请导入.xlsx或.xls格式的文档");
                    }
                }
                if (workbook == null)
                {
                    result = null;
                    return result;
                }
                ISheet sheetAt = workbook.GetSheetAt(0);
                if (deleteEndRowIndex != 0)
                {
                    for (int i = deleteEndRowIndex; i >= 1; i--)
                    {
                        sheetAt.ShiftRows(i, i + 1, -1);
                    }
                }

                IRow row = sheetAt.GetRow(sheetAt.FirstRowNum);
                List<int> list = new List<int>();
                for (int i = 0; i < (int)row.LastCellNum; i++)
                {
                    if (isUseNewColumnName)
                    {
                        dataTable.Columns.Add(new DataColumn("Cols" + i.ToString()));
                    }
                    else
                    {
                        object valueType = this.GetValueType(row.GetCell(i));
                        if (valueType == null || valueType.ToString() == string.Empty)
                        {
                            dataTable.Columns.Add(new DataColumn("Cols" + i.ToString()));
                        }
                        else
                        {
                            dataTable.Columns.Add(new DataColumn(valueType.ToString()));
                        }
                    }

                    list.Add(i);
                }
                for (int j = sheetAt.FirstRowNum + 1; j <= sheetAt.LastRowNum; j++)
                {
                    DataRow dataRow = dataTable.NewRow();
                    bool bCellIsNull = false;
                    foreach (int current in list)
                    {
                        if (sheetAt.GetRow(j) == null)
                            break;
                        ICell cell = sheetAt.GetRow(j).GetCell(current);
                        dataRow[current] = this.GetValueType(cell);
                        if (dataRow[current] != null && dataRow[current].ToString() != string.Empty)
                        {
                            bCellIsNull = true;
                        }
                    }
                    if (bCellIsNull)
                    {
                        dataTable.Rows.Add(dataRow);
                    }
                }
            }
            result = dataTable;
            return result;
        }

        /// <summary>
        /// 获取单元格类型
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private object GetValueType(ICell cell)
        {
            bool flag = cell == null;
            object result;
            if (flag)
            {
                result = null;
            }
            else
            {
                switch (cell.CellType)
                {
                    case CellType.Numeric:                  //数值
                        result = cell.NumericCellValue;
                        return result;
                    case CellType.String:                   //文本
                        result = cell.StringCellValue;
                        return result;
                    case CellType.Blank:                    //空值
                        result = null;
                        return result;
                    case CellType.Boolean:                  //布尔类型
                        result = cell.BooleanCellValue;
                        return result;
                    case CellType.Error:                    //二进制
                        result = cell.ErrorCellValue;
                        return result;
                    case CellType.Formula:                  //公式
                        //这里只能处理数值公式。其他公式将会被转换成数值类型,如:日期公式。
                        result = cell.NumericCellValue;
                        return result;

                }

                result = "=" + cell.CellFormula;
            }
            return result;
        }

        #endregion

感谢支持,有写得不好的地方还望多多指教。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值