zoukankan      html  css  js  c++  java
  • 如何将 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);
  • 相关阅读:
    SpringBoot
    JS
    域渗透之NTLM Relay
    域渗透之 pre-auth用户枚举
    mysql 必知必会整理—sql 正则表达[五]
    mysql 必知必会整理—sql 简单语句[二]
    redis 简单整理——缓存设计[三十二]
    mysql 必知必会整理——mysql 介绍[一]
    redis 简单整理——哨兵原理[三十一]
    redis 简单整理——客户端哨兵模式[三十]
  • 原文地址:https://www.cnblogs.com/fxck/p/13076916.html
Copyright © 2011-2022 走看看