简体   繁体   English

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

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

Im trying to read and import excel data to a Datatable. 我试图读取并将Excel数据导入Datatable。 But Im using OLEDB Connection,. 但我使用OLEDB连接,。 What can I use that needs NO INSTALLATION aside from OLEDB that can read and import excel data to datatable? 除了可以读取和导入excel数据到datatable的OLEDB之外,我可以使用哪些不需要安装?

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# IM使用ASP.Net2.0 .Net FrameWork 4.0和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: 使用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());
            }

If you do not want to use an OLEDB connection, try the code below. 如果您不想使用OLEDB连接,请尝试以下代码。 You'll need to adapt the code to your particular use. 您需要根据特定用途调整代码。 The code assumes that you've declared the excel objects already. 代码假定您已经声明了excel对象。 Do not initialize them inside of the try label as the finally label will not be able to see them. 不要在try标签内初始化它们,因为finally标签将无法看到它们。 Instead, initialize them as null just under the method declaration, then declare them as the appropriate Excel Interop object inside of the try label. 相反,在方法声明下将它们初始化为null,然后将它们声明为try标签内的相应Excel Interop对象。

EDIT: Depending on the size of your excel sheet, this can be slower than reading with an OLEDB connection. 编辑:根据excel表的大小,这可能比使用OLEDB连接读取要慢。 I tested on a table with 4000 rows and it takes about 4 minutes. 我在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);
}

Here's the code for releaseObject. 这是releaseObject的代码。 Marshal = System.Runtime.InteropServices.Marshal (add this to the dependencies list): 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