简体   繁体   中英

How to import specific columns and rows of excel data to datagridview WITHOUT OLEDB in C#

I made a simple standalone program for work that auto maps network drives. The program uses a DataGridView to list all the drive letter and paths and the code I wrote reads the entries in the DataGridView and maps the drives based from that - also getting the drive letter and path from a specific excel sheet.

That specific excel file keeps track of certain information of a user's computer using VB code. The 3rd worksheet, named “Drives”, is where the network drives reside in. The drive letter and path are in column C and D. There are no headers except for the name “Network drives” on row 2 before it starts on row 3. Unfortunately, after row 29, entries for outlook pst files start.

With my limited knowledge on C# (I'm new to C#), I somehow managed to create this:

public void FileSelect()
    {
        string filePath = string.Empty;
        string fileExt = string.Empty;
        OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file
        file.Filter = "Discovery Excel|*.xlsm| CSV (Coming Soon)| *.csv";
        file.Title = "Please select a valid data file";

        if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK) //if there is a file choosen by the user  
        {
            filePath = file.FileName; //get the path of the file  
            fileExt = Path.GetExtension(filePath); //get the file extension 
            if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsm") == 0)
            {
                try
                {

                    DataTable dtExcel = new DataTable();
                    dtExcel = ReadExcel(filePath, fileExt); //read file  
                    InfoTB.Visible = false;
                    dataGridView1.Visible = true;
                    FileSelectBT.Visible = false;
                    ManualBT.Visible = false;
                    RunBT.Visible = true;
                    ExitBT.Visible = true;
                    RunBT.Location = new System.Drawing.Point(109, 334);
                    ExitBT.Location = new System.Drawing.Point(190, 334);
                    dataGridView1.DataSource = dtExcel;
                    dataGridView1.AutoResizeColumns();
                    dataGridView1.Columns[0].HeaderText = "Drive Letter";
                    dataGridView1.Columns[1].HeaderText = "Drive Path";
                    for (int i = 1; i < dataGridView1.RowCount - 1; i++)
                    {
                        if (dataGridView1.Rows[i].Cells[0].Value.ToString() == "" || dataGridView1.Rows[i].Cells[1].Value.ToString() == "")
                        {
                            dataGridView1.Rows.RemoveAt(i);
                            i--;
                        }
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    ManualMode();
                    OpenExcel(filePath);
                    TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
                    txt.Write(ex.ToString());
                    txt.Close();
                }
            }
            else
            {
                MessageBox.Show("Please choose .xlsm or .CSV file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error  
            }
        } 
    }


    public DataTable ReadExcel(string fileName, string fileExt)
    {
        string conn = string.Empty;
        DataTable dtexcel = new DataTable();
        conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + fileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";"; //loading the Access engine to load/read the Excel file  
        using (OleDbConnection con = new OleDbConnection(conn))
        {
            try
            {
                OleDbDataAdapter oleAdpt = new OleDbDataAdapter("Select TOP 24 F3,F4 FROM [Drives$]", conn); //read data from sheet 3 which should be the drives 
                oleAdpt.Fill(1, 24, dtexcel); //fill excel data into dataTable  
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ManualMode();
                OpenExcel(fileName);
                TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+ "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
                txt.Write(ex.ToString());
                txt.Close();
            }
        }
        return dtexcel;
    }

And this code worked!

Here's photo of what the program looks like when it has some entries

Unfortunately, the Microsoft.ACE.OLEDB.12.0 is not reliable when it comes to moving the program from one computer to another. I am not able to install ACE on every computer at work, so I must find another method to read the Excel files specifically without the need to use OLEDB.

I did look around to find an alternative solution, but the stuff I've found seemed to be focusing on specific starting rows instead of the ending rows.

Though to be fair, I'm new to C# so I may have overlooked something that would help with my program.

That said, is there an alternative to OLEDB for this situation?

As stated in the comments by PaulF, Excel Interop is a possible solution, saving the need to use any external libraries.

The following is assuming that your data will always be in C3:D29 and also assumes that the data in the worksheet is valid:

public DataTable ReadExcel(string fileName)
{ 
    var excel = new Excel.Application();
    var wkb = excel.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    var sheet = wkb.Sheets["Drives"] as Excel.Worksheet;

    var range = sheet.Range[sheet.Cells[3, 3], sheet.Cells[29, 4]];
    var data = range.Value2;

    var dt = new DataTable();
    dt.Columns.Add("Drive");
    dt.Columns.Add("Path");

    for (int i = 1; i <= range.Rows.Count; i++)
    {
        dt.Rows.Add(data[i, 1], data[i, 2]);
    }

    return dt;
}

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