zoukankan      html  css  js  c++  java
  • C# 读取Excel到DataTable两种方式对比

    方式一 OLEDB读取 数据库引擎

    优点:读取速度快,依据sheet排序读取

    缺点:对于Excel版本依赖强,无法读取指定sheet

    错误提示:本地计算机未指定 Microsoft.ACE.OLEDB.12.0

    解决方法:win7(64位)+office 2010(64位) 更改目标平台为X86

    win10(64位)+office 2010(64位) 更改目标平台无效,下载安装AccessDatabaseEngine.exe,重启无效,项目需求采用方式二

    注:2019年7月20日之前和平台无关,均可使用(可能office服务被禁,公司特殊),情况紧急,采用方式二。

    代码如下:

    public static List<DataTable> excelToDataTable(string filePath)
            {
                List<DataTable> dtList = new List<DataTable>();
                string connStr = "";
                string fileType = System.IO.Path.GetExtension(filePath);
                if (string.IsNullOrEmpty(fileType)) return null;
                if (fileType == ".xls")
                    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";" + ";Extended Properties="Excel 8.0;HDR=YES;IMEX=1"";
                else
                    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath + ";" + ";Extended Properties="Excel 12.0;HDR=N0;IMEX=1"";
                string sql_F = "Select * FROM [{0}]";
                OleDbConnection conn = null;
                OleDbDataAdapter da = null;
                DataTable dtSheetName = null;
                DataSet ds = new DataSet();
                DataTable dtNew = new DataTable();
                try
                {
                    // 初始化连接,并打开    
                    conn = new OleDbConnection(connStr);
                    conn.Open();
                    // 获取数据源的表定义元数据 
                    string SheetName = "";
                    dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
                    // 初始化适配器           
                    da = new OleDbDataAdapter();
              
                    for (int i = 0; i < dtSheetName.Rows.Count; i++)
                    {
                        DataTable dt = new DataTable();
                        SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];
                        if (SheetName.Contains("$") && !SheetName.Replace("'", "").EndsWith("$"))
                        {
                            continue;
                        }
                        da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName), conn);
                        dt.TableName = i.ToString();
                        da.Fill(dt);
                        dtList.Add(dt);     
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                }
                finally
                {
                    // 关闭连接             
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                        da.Dispose();
                        conn.Dispose();
                    }
                }
                return dtList;
            }

    方式二 Excel引擎读取 Microsoft.Office.Interop.Excel

    使用方式:引用 Microsoft.Office.Interop.Excel 调用Excel读取

    优点:不受Excel版本限制,可指定sheet读取

    缺点:读取速度慢,几千数据10分钟

    代码如下:

     public static List<DataTable> excelToDataTable(string filePath,bool hasTitle = false)
            {
                List<DataTable> dtList = new List<DataTable>();
                int iRowCount;
                int iColCount;

                Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
                Microsoft.Office.Interop.Excel.Sheets sheets;
                object oMissiong = System.Reflection.Missing.Value;
                Microsoft.Office.Interop.Excel.Workbook workbook = null;
                DataTable dt = new DataTable();

                try
                {
                    if (app == null) return null;
                    workbook = app.Workbooks.Open(filePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong,
                        oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
                    sheets = workbook.Worksheets;

                    //将数据读入到DataTable中
                    Microsoft.Office.Interop.Excel.Worksheet worksheet = sheets.get_Item(1);
                    if (worksheet == null) return null;
                    iRowCount = worksheet.UsedRange.Rows.Count;
                    iColCount = worksheet.UsedRange.Columns.Count;
                    //生成列头
                    for (int i = 0; i < iColCount; i++)
                    {
                        var name = "column" + i;
                        if (hasTitle)
                        {
                            var txt = ((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, i + 1]).Text.ToString();
                            if (!string.IsNullOrWhiteSpace(txt)) name = txt;
                        }
                        while (dt.Columns.Contains(name)) name = name + "_1";//重复行名称会报错。
                        dt.Columns.Add(new DataColumn(name, typeof(string)));
                    }
                    //生成行数据
                    Microsoft.Office.Interop.Excel.Range range;
                    int rowIdx = hasTitle ? 2 : 1;
                    for (int iRow = rowIdx; iRow <= iRowCount; iRow++)
                    {
                        DataRow dr = dt.NewRow();
                        for (int iCol = 1; iCol <= iColCount; iCol++)
                        {
                            range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[iRow, iCol];
                            dr[iCol - 1] = (range.Value2 == null) ? "" : range.Text.ToString();
                        }
                        dt.Rows.Add(dr);
                    }
                   dtList.Add(dt);
                    for (int i = 2; i <= sheets.Count; i++)
                    {
                        worksheet=sheets.get_Item(i);//读取第一张表 
                        iRowCount = worksheet.UsedRange.Rows.Count;
                        iColCount = worksheet.UsedRange.Columns.Count;
                        //生成列头
                        for (int j = 0; j < iColCount; j++)
                        {
                            var name = "column" + i;
                            if (hasTitle)
                            {
                                var txt = ((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, j + 1]).Text.ToString();
                                if (!string.IsNullOrWhiteSpace(txt)) name = txt;
                            }
                            while (dt.Columns.Contains(name)) name = name + "_1";//重复行名称会报错。
                            dt.Columns.Add(new DataColumn(name, typeof(string)));
                        }
                        //生成行数据
                        Microsoft.Office.Interop.Excel.Range range1;
                        int rowIdx1 = hasTitle ? 2 : 1;
                        for (int iRow = rowIdx1; iRow <= iRowCount; iRow++)
                        {
                            DataRow dr = dt.NewRow();
                            for (int iCol = 1; iCol <= iColCount; iCol++)
                            {
                                range1 = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[iRow, iCol];
                                dr[iCol - 1] = (range1.Value2 == null) ? "" : range1.Text.ToString();
                            }
                            dt.Rows.Add(dr);
                        }
                        dtList.Add(dt);
                    }
                    return dtList;
                }
                catch { return null; }
                finally
                {
                    workbook.Close(false, oMissiong, oMissiong);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
                    workbook = null;
                    app.Workbooks.Close();
                    app.Quit();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                    app = null;
                }
            }

  • 相关阅读:
    Linux信号列表(zz)
    TCP状态转移图学习总结
    UNP学习笔记之四select和poll
    RSS2.0结构
    UNP学习笔记二简单的并发服务器(concurrent servers)
    js面向对象基础(zz)
    libevent introduction
    Linux下Makefile的automake生成全攻略(zz)
    UNP学习笔记之三POSIX Signal Handling
    关于网络编程(服务端)的一些笔记(zz)
  • 原文地址:https://www.cnblogs.com/arvinzd/p/11321513.html
Copyright © 2011-2022 走看看