zoukankan      html  css  js  c++  java
  • Excel转化成DataTable实现:NPOI和OLEDb

    使用两种方式实现的excel数据转化成DataSet,再结合前一篇的DataTable转化为实体,就可以解决excel到实体之间的转化。

    代码如下:

    首先定义一个接口:

        public interface IExcelAccess
        {
            DataSet Load(ExcelConfig config);
        }
    public class ExcelConfig
        {
            /// <summary>
            /// 文件存储路径
            /// </summary>
            public string Path { get; set; }
    
            /// <summary>
            /// 文件表头所在行索引
            /// </summary>
            public int HeaderIndex { get; set; }
        }

    再来看一下使用NPOI的实现:

    public class NpoiExcelAccess : IExcelAccess
        {
            /// <summary>
            /// 根据文件扩展名,获取workbook实例
            /// </summary>
            /// <param name="ext"></param>
            /// <returns></returns>
            private IWorkbook GetWorkBook(string ext, Stream stream)
            {
                IWorkbook workbook = null;
    
                switch (ext)
                {
                    case ".xlsx":
                        workbook = new XSSFWorkbook(stream);
                        break;
                    case ".xls":
                        workbook = new HSSFWorkbook(stream);
                        break;
                    default:
                        break;
                }
    
                return workbook;
            }
    
            /// <summary>
            /// 加载数据,可设置跳过前几行
            /// </summary>
            /// <param name="path"></param>
            /// <param name="skipRows"></param>
            /// <returns></returns>
            public DataSet Load(ExcelConfig config)
            {
                using (var fileStream = new FileStream(config.Path, FileMode.Open, FileAccess.Read))
                {
                    var ds = new DataSet();
                    var ext = Path.GetExtension(config.Path);
    
                    // 新建IWorkbook对象 
                    var workbook = this.GetWorkBook(ext, fileStream);
    
                    for (int i = 0; i < workbook.NumberOfSheets; i++)
                    {
                        ISheet sheet = workbook.GetSheetAt(i);
                        DataTable dt = GetDataTable(sheet, config.HeaderIndex);
                        ds.Tables.Add(dt);
                    }
    
                    return ds;
                }
            }
    
            private DataTable GetDataTable(ISheet sheet, int headerIndex)
            {
                var dt = new DataTable();
                // 获取表头行
                var headerRow = sheet.GetRow(headerIndex);
                var cellCount = GetCellCount(sheet, headerIndex);
    
                // 设置表头
                for (int i = 0; i < cellCount; i++)
                {
                    if (headerRow.GetCell(i) != null)
                    {
                        dt.Columns.Add(headerRow.GetCell(i).StringCellValue, typeof(string));
                    }
                }
                
                for (int i = headerIndex + 1; i <= sheet.LastRowNum; i++)
                {
                    IRow row = sheet.GetRow(i);
                    DataRow dr = dt.NewRow();
                    FillDataRow(row, ref dr);
                    dt.Rows.Add(dr);
                }
    
                dt.TableName = sheet.SheetName;
                return dt;
    
            }
    
            private void FillDataRow(IRow row, ref DataRow dr)
            {
                if (row != null)
                {
                    for (int j = 0; j < dr.Table.Columns.Count; j++)
                    {
                        ICell cell = row.GetCell(j);
    
                        if (cell != null)
                        {
                            switch (cell.CellType)
                            {
                                case CellType.Blank:
                                    dr[j] = DBNull.Value;
                                    break;
                                case CellType.Boolean:
                                    dr[j] = cell.BooleanCellValue;
                                    break;
                                case CellType.Numeric:
                                    if (DateUtil.IsCellDateFormatted(cell))
                                    {
                                        dr[j] = cell.DateCellValue;
                                    }
                                    else
                                    {
                                        dr[j] = cell.NumericCellValue;
                                    }
                                    break;
                                case CellType.String:
                                    dr[j] = cell.StringCellValue;
                                    break;
                                case CellType.Error:
                                    dr[j] = cell.ErrorCellValue;
                                    break;
                                case CellType.Formula:
                                    // cell = evaluator.EvaluateInCell(cell) as HSSFCell;
                                    dr[j] = cell.ToString();
                                    break;
                                default:
                                    throw new NotSupportedException(string.Format("Catched unhandle CellType[{0}]", cell.CellType));
                            }
                        }
                    }
                }
            }
    
            /// <summary>
            /// 获取表头列数
            /// </summary>
            /// <param name="sheet"></param>
            /// <param name="skipRows"></param>
            /// <returns></returns>
            private int GetCellCount(ISheet sheet, int headerIndex)
            {
                var headerRow = sheet.GetRow(headerIndex);
    
                return headerRow.LastCellNum;
            }
        }

    最后看一下使用OLEDB的实现,这里,我只实现了excel2003的版本,07版本的总是失败,查了原因,是需要在本机安装一个组件才能支持导入.xlsx文件。

     public class OleDbExcelAccess : IExcelAccess
        {
            private string strConn;
    
            public OleDbExcelAccess()
            {
                //TODO 需要根据扩展名,来决定 使用哪一种连接字符串
                strConn = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = {0};Extended Properties='Excel 8.0;IMEX=1;HDR=NO'";
            }
    
            public DataSet Load(ExcelConfig config)
            {
                var ds = new DataSet();
                var sheets = GetSheetNames(config.Path);
                var strConnTmp = string.Format(strConn, config.Path);
    
                foreach (string sheet in sheets)
                {
                    using (var oleConn = new OleDbConnection(strConnTmp))
                    {
                        var strsql = "SELECT * FROM [" + sheet + "]";
                        var oleDaExcel = new OleDbDataAdapter(strsql, oleConn);
                        oleConn.Open();
                        oleDaExcel.Fill(ds, sheet);
                    }
                }
    
                return ds;
            }
    
            /// <summary>
            /// 获取Excel的所有的sheet
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
            private string[] GetSheetNames(string path)
            {
                DataTable dt = new DataTable();
                if (File.Exists(path))
                {
                    string strConnTmp = string.Format(strConn, path);
                    using (var conn = new OleDbConnection(strConnTmp))
                    {
                        conn.Open();
                        //返回Excel的架构,包括各个sheet表的名称,类型,创建时间和修改时间等    
                        dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
                    }
                    //包含excel中表名的字符串数组
                    var sheetNames = new List<string>();
                    for (int k = 0; k < dt.Rows.Count; k++)
                    {
                        string tableName = dt.Rows[k]["TABLE_NAME"].ToString();
                        //修正出现兼容性视图名称时过滤表名
                        if (!tableName.Substring(tableName.Length - 1).Equals("_"))
                        {
                            sheetNames.Add(tableName);
                        }
                    }
                    return sheetNames.ToArray();
    
                }
                return null;
    
            }
        }

    最后看一下客户端的调用 :

     private void TestExcelImport()
            {
                var excelFile = Path.Combine("C:\Users\hankk\Desktop\ICON", "2003版本.xls");
    
                ExcelConfig config = new ExcelConfig()
                {
                    Path = excelFile,
                    HeaderIndex = 1
                };
    
                IExcelAccess npoiAccess = new NpoiExcelAccess();
                var npoiDs = npoiAccess.Load(config);
    
                IExcelAccess oleDbAccess = new OleDbExcelAccess();
                var oleDs = oleDbAccess.Load(config);
            }

    代码已上传到github: https://github.com/hankuikuide/ExcelAccessor

  • 相关阅读:
    linux系统编程程序员必备
    postgresql查询优化之GIN(Generalized Inverted Index)索引与全文检索
    postgresql并行执行
    lightdb for postgresql日志详解
    PostgreSQL 使用数组类型
    postgresql wal文件误删恢复
    汉语词性标注集
    postgresql----JSON类型、函数及全文检索的支持
    postgresql等待事件之wait_event为空解析
    lightdb for pg查看锁
  • 原文地址:https://www.cnblogs.com/hankuikui/p/8098149.html
Copyright © 2011-2022 走看看