如何将 Excel 转换为 DataTable 数据

/// <summary>
/// Excel 帮助类
/// </summary>
public static class ExcelHelper
{
    /// <summary>
    /// 将 Excel 转换为 DataTable
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <param name="sheetIndex">表下标 从0开始</param>
    /// <param name="rowIndex">行下标 从1开始</param>
    /// <param name="header"> 是否排除excel中第一行</param>
    /// <returns>DataTable</returns>
    public static DataTable ExcelToDataTable(string filePath, int sheetIndex, int rowIndex, bool header = true)
    {
        var ext = CheckExt(filePath);

        if (ext == "208207")//xls
            return ToDataTable2003(filePath, sheetIndex, rowIndex, header);

        if (ext == "8075")//xlsx
            return ToDataTable2007(filePath, sheetIndex, header);

        return new DataTable();
    }

    #region Private Method

    /// <summary>
    /// 通过文件头信息判断文件类型
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private static string CheckExt(string path)
    {
        var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
        var r = new BinaryReader(fs);

        var bx = string.Empty;

        try
        {
            byte buffer = r.ReadByte();
            bx = buffer.ToString();
            buffer = r.ReadByte();
            bx += buffer.ToString();

            // 208207 xls
            // 8075 xlsx
        }
        catch (Exception)
        {
            //throw;
        }
        finally
        {
            r.Close();
            fs.Close();
        }
        return bx;
    }

    /// <summary>
    /// 将 2003 Excel 转换为 DataTable
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <param name="sheetIndex">表下标 从0开始</param>
    /// <param name="rowIndex">行下标 从1开始</param>
    /// <param name="header"> excel中第一行是否属于列</param>
    /// <returns>DataTable</returns>
    private static DataTable ToDataTable2003(string filePath, int sheetIndex, int rowIndex, bool header)
    {
        var dt = new DataTable(Path.GetFileNameWithoutExtension(filePath) + "_Sheet" + sheetIndex);

        using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            var workbook = new HSSFWorkbook(file);
            var sheet = workbook.GetSheetAt(sheetIndex);

            sheet.SetColumnHidden(0, false);
            sheet.SetColumnHidden(1, false);
            sheet.SetColumnHidden(2, false);

            var rows = sheet.GetRowEnumerator();
            for (int i = 0; i < rowIndex; i++)
            {
                rows.MoveNext();
            }

            var row = (HSSFRow)rows.Current;

            for (var i = 0; i < row.LastCellNum; i++)
            {
                var columnName = header ? row.GetCell(i).StringCellValue : i.ToString();
                dt.Columns.Add(columnName, typeof(string));
            }

            if (!header)
            {
                var dataRow = dt.NewRow();
                for (var i = 0; i < row.LastCellNum; i++)
                {
                    var item = row.GetCell(i);

                    dataRow[i] = GetRow(item);
                }
                dt.Rows.Add(dataRow);
            }

            while (rows.MoveNext())
            {
                row = (HSSFRow)rows.Current;
                var dataRow = dt.NewRow();
                bool isNull = false;//是否空行
                for (var i = 0; i < row.LastCellNum; i++)
                {
                    var item = row.GetCell(i);
                    var _row = GetRow(item);
                    if (_row != null)
                    {
                        dataRow[i] = _row;
                        if (!string.IsNullOrWhiteSpace(dataRow[i].ToString()))
                        {
                            isNull = true;//设置非空
                        }
                    }
                }
                if (isNull)
                {
                    dt.Rows.Add(dataRow);
                }
            }
        }

        return dt;
    }

    /// <summary>
    /// 将 2007 Excel 转换为 DataTable
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <param name="index">表下标 从0开始</param>
    /// <param name="header"> excel中第一行是否属于列</param>
    /// <returns>DataTable</returns>
    private static DataTable ToDataTable2007(string filePath, int index, bool header)
    {
        var dt = new DataTable(Path.GetFileNameWithoutExtension(filePath) + "_Sheet" + index);

        using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            var workbook = new XSSFWorkbook(file);
            var sheet = workbook.GetSheetAt(index);

            var rows = sheet.GetRowEnumerator();
            rows.MoveNext();
            var row = (XSSFRow)rows.Current;

            for (var i = 0; i < row.LastCellNum; i++)
            {
                var columnName = header ? row.GetCell(i).StringCellValue : i.ToString();
                dt.Columns.Add(columnName, typeof(string));
            }

            if (!header)
            {
                var dataRow = dt.NewRow();
                for (var i = 0; i < row.LastCellNum; i++)
                {
                    var item = row.GetCell(i);

                    dataRow[i] = GetRow(item);
                }
                dt.Rows.Add(dataRow);
            }

            while (rows.MoveNext())
            {
                row = (XSSFRow)rows.Current;
                var dataRow = dt.NewRow();
                bool isNull = false;//是否空行
                for (var i = 0; i < row.LastCellNum; i++)
                {
                    var item = row.GetCell(i);
                    var _row = GetRow(item);
                    if (_row != null)
                    {
                        dataRow[i] = _row;
                        if (!string.IsNullOrWhiteSpace(dataRow[i].ToString()))
                        {
                            isNull = true;//设置非空
                        }
                    }
                }
                if (isNull)
                {
                    dt.Rows.Add(dataRow);
                }
            }
        }

        return dt;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="cell"></param>
    /// <returns></returns>
    private static object GetRow(ICell cell)
    {
        if (cell == null)
            return null;
        switch (cell.CellType)
        {
            case CellType.Blank: //BLANK:
                return null;
            case CellType.Boolean: //BOOLEAN:
                return cell.BooleanCellValue;
            case CellType.Numeric: //NUMERIC:
                return cell.NumericCellValue;
            case CellType.String: //STRING:
                return cell.StringCellValue;
            case CellType.Error: //ERROR:
                return cell.ErrorCellValue;
            case CellType.Formula: //FORMULA:
            default:
                return "=" + cell.CellFormula;
        }
    }

    #endregion
}

调用时使用,内中默认处理了 xls 与 xlsx 类型的 Excel 格式,使两种格式可以兼容。

ExcelHelper.ExcelToDataTable(path, 0, 1);

 

posted @ 2019-01-04 10:14  Jöhan  阅读(372)  评论(0编辑  收藏  举报