繁体   English   中英

在C#中将Excel读取到Datatable / DataSet

[英]Read Excel to Datatable/DataSet in C#

我试图读取并将Excel数据导入Datatable。 但我使用OLEDB连接,。 除了可以读取和导入excel数据到datatable的OLEDB之外,我可以使用哪些不需要安装?

我在服务器中部署我的项目,我不允许在服务器中安装任何插件或软件。

IM使用ASP.Net2.0 .Net FrameWork 4.0和c#

你可以尝试下面的代码:

public class ExcelReader
{
    public static DataSet ReadExcel(string excelFilePath, string workSheetName)
    {
        DataSet dsWorkbook = new DataSet();

        string connectionString = string.Empty;

        switch (Path.GetExtension(excelFilePath).ToUpperInvariant())
        {
            case ".XLS":
                connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=Excel 8.0;", excelFilePath);
                break;

            case ".XLSX":
                connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", excelFilePath);
                break;

        }

        if (!String.IsNullOrEmpty(connectionString))
        {
            string selectStatement = string.Format("SELECT * FROM [{0}$]", workSheetName);

            using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectStatement, connectionString))
            {                   
                adapter.Fill(dsWorkbook, workSheetName);  
            }
        }

        return dsWorkbook;
    }

}

使用oledb读取excel文件并将其导入dataSet:

using Excel = Microsoft.Office.Interop.Excel; 

-

      try
            {
                System.Data.OleDb.OleDbConnection MyConnection ;
                System.Data.DataSet DtSet ;
                System.Data.OleDb.OleDbDataAdapter MyCommand ;
                MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\\mydoc.xls';Extended Properties=Excel 8.0;");
                //MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\\mydoc.xls';Extended Properties=Excel 12.0;"); 
                MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
                MyCommand.TableMappings.Add("Table", "TestTable");
                DtSet = new System.Data.DataSet();
                MyCommand.Fill(DtSet);
                dataGridView1.DataSource = DtSet.Tables[0];
                MyConnection.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show (ex.ToString());
            }

如果您不想使用OLEDB连接,请尝试以下代码。 您需要根据特定用途调整代码。 代码假定您已经声明了excel对象。 不要在try标签内初始化它们,因为finally标签将无法看到它们。 相反,在方法声明下将它们初始化为null,然后将它们声明为try标签内的相应Excel Interop对象。

编辑:根据excel表的大小,这可能比使用OLEDB连接读取要慢。 我在4000行的桌子上进行了测试,大约需要4分钟。

try
{
    //Declare variables
    object rowIndex = 2; //Row to start on. Change to 1 if you do not have header text
    DataRow row;
    System.Data.DataTable dt = new System.Data.DataTable();
    int index = 0;

    //Manual column headers - set up for if you are not using the provided column headers
    dt.Columns.Add("Column Name"); //row[0]
    dt.Columns.Add("Column 2"); //row[1]
    dt.Columns.Add("Column 3"); //row[2]
    dt.Columns.Add("Column 4"); //row[3]

    //Now for actually reading the values
    while (((Excel.Range)xlWorksheet.Cells[rowIndex, 1]).Value2 != null)
    {
        row = dt.NewRow();

        //row[column#]
        //for cells[rowIndex, 1]: rowIndex is the row you are reading from, 1 is the source column. This is where you would ignore columns altogether if you needed to.
        //Value2 returns the value of the cell. I don't remember what Value1 returns (cell type?)
        row[0] = Convert.ToString(((Excel.Range)xlWorksheet.Cells[rowIndex, 1]).Value2);

        //You can use a switch statement
        //Notice, column index is 3, which means I have effectively skipped column 2
        string valColumn2 = Convert.ToString(((Excel.Range)xlWorksheet.Cells[rowIndex, 3]).Value2);
        switch (valColumn2)
        {
            case "false":
            {
                row[1] = "0";
                break;
            }
            case "true":
            {
                row[1] = "1";
                break;
            }
            default:
            {
                row[1] = valColumn2;
                break;
            }
        }

        //You can use a date. OADate assumes it's Excel's date format, which is a double.
        //Note that my column index is 2, the column I skipped before. This shows you can collect data from columns in a non-numeric order.
        try
        {
            row[2] = DateTime.FromOADate(((Excel.Range)xlWorksheet.Cells[rowIndex, 2]).Value2);
        }
        catch //In case it's not a date for some reason- i.e. you hand it a header row.
        {
            row[2] = "";
        }

        //You can also display cell values as integers. Say you have a column with a count of items. Additionally, ToInt32 recognizes null values and displays them as 0
        row[3] = Convert.ToInt32(((Excel.Range)xlWorksheet.Cells[rowIndex, 3]).Value2);

        //We're done, just a few things to wrap up...
        index++;
        rowIndex = 2 + index; //The initial value of row index is 2. When we reach this point in the first run, index changes to 1, so rowIndex = 2 + 1 = 3
        dt.Rows.Add(row); //Add the row to our datatable

        //Optional - if you want to watch each row being added. If not, put it outside of the while loop.
        dataGridView1.DataSource = dt;
    }
}
finally
{
    //Release all COM RCWs.
    //releaseObject will do nothing if null is passed, so don't worry if it's null
    //If you do not release the objects properly (like below), you WILL end up with ghost EXCEL.EXE processes.
    //This will cause runtime errors (unable to access file because it's already open), as well as cause some serious lag once you get enough of them running.
    releaseObject(xlWorksheet);
    releaseObject(xlWorkbook);
    if (xlApp != null)
        { xlApp.Quit(); }
    releaseObject(xlApp);
}

这是releaseObject的代码。 Marshal = System.Runtime.InteropServices.Marshal(将其添加到依赖项列表):

private void releaseObject(object obj)
{
    if (obj != null && Marshal.IsComObject(obj))
    {
        Marshal.ReleaseComObject(obj);
    }
    obj = null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM