简体   繁体   中英

Read Excel to Datatable/DataSet in C#

Im trying to read and import excel data to a Datatable. But Im using OLEDB Connection,. What can I use that needs NO INSTALLATION aside from OLEDB that can read and import excel data to datatable?

Im deploying my project in the server and I am not allowed to install any plugins or software in the server.

IM using ASP.Net2.0 .Net FrameWork 4.0 and c#

You can try below code :

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;
    }

}

Read and import excel file into dataSet using oledb:

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());
            }

If you do not want to use an OLEDB connection, try the code below. You'll need to adapt the code to your particular use. The code assumes that you've declared the excel objects already. Do not initialize them inside of the try label as the finally label will not be able to see them. Instead, initialize them as null just under the method declaration, then declare them as the appropriate Excel Interop object inside of the try label.

EDIT: Depending on the size of your excel sheet, this can be slower than reading with an OLEDB connection. I tested on a table with 4000 rows and it takes about 4 minutes.

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);
}

Here's the code for releaseObject. Marshal = System.Runtime.InteropServices.Marshal (add this to the dependencies list):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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