Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multi-sheet import with oledb netting "_xlnm#_FilterDatabase" as sheet names

Tags:

c#

excel

oledb

i have an excel with multi-sheets that i want to import
the code is fairly simple and basic and should work
but my sheetnames keep coming back as "_xlnm#_FilterDatabase" in the debugger
and is the root of my prob

here is the relevant portion of the code:

        string sheetName = "";
        file = HostingEnvironment.MapPath("~/files/master1.xlsx");
        xConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + file + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";";
        using (OleDbConnection connection = new OleDbConnection(xConnStr))
        {
            // get sheet names
            connection.Open();
            DataTable sheets = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

            // eeo10 (2nd tab: first sheet to be imported)
            sheetName = sheets.Rows[1]["TABLE_NAME"].ToString();
            OleDbCommand command = new OleDbCommand("Select * FROM ["+sheetName+"]", connection);

            // Create DbDataReader to Data Worksheet                
            using (OleDbDataReader dr = command.ExecuteReader())
            {

                // Bulk Copy to SQL Server
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnx))
                {
                    bulkCopy.ColumnMappings.Add("code", "id");
                    bulkCopy.ColumnMappings.Add("category10", "category");

                    bulkCopy.DestinationTableName = "eeo10";
                    bulkCopy.WriteToServer(dr);
                }
            }

            // eeo14 (3rd tab: second sheet to be imported)
            sheetName = sheets.Rows[2]["TABLE_NAME"].ToString();
            command = new OleDbCommand("Select * FROM [" + sheetName + "]", connection);

            DataTable cols = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, sheetName, null });
            foreach (DataRow r in cols.Rows)
            {
                System.Diagnostics.Debug.WriteLine("{0} = {1}", r["COLUMN_NAME"], r["ORDINAL_POSITION"]);
            }

            // Create DbDataReader to Data Worksheet                
            using (OleDbDataReader dr = command.ExecuteReader())
            {

                // Bulk Copy to SQL Server
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnx))
                {
                    bulkCopy.ColumnMappings.Add("code", "id");
                    bulkCopy.ColumnMappings.Add("category14", "category");

                    bulkCopy.DestinationTableName = "eeo14";
                    bulkCopy.WriteToServer(dr);
                }
            }
        }

so as stated before
the debugger returns sheetName="_xlnm#_FilterDatabase"
which weirdly enough the first one eeo10 works
but eeo14 doesnt because its still trying working with the eeo10 sheet

here maybe some other relevant pieces of information:
- i have turned off autofilter in the workbook
- i put in the column header printout just to confirm which sheet it was reading

any insights would be apprec
thanks so much!

like image 598
toy Avatar asked Apr 12 '14 18:04

toy


1 Answers

Excel creates a hidden sheet each time you filter on a sheet and all though this sheet should not be available when retrieving the sheet names. Here is a piece of code that will help you get the sheet names using System.Data.OleDb:

class Retriever
{
    public List<SheetName> GetSheetNames(OleDbConnection conn)
    {
        List<SheetName> sheetNames = new List<SheetName>();
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }
        DataTable excelSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
        foreach (DataRow row in excelSchema.Rows)
        {
            if (!row["TABLE_NAME"].ToString().Contains("FilterDatabase"))
            {
               sheetNames.Add(new SheetName() { sheetName = row["TABLE_NAME"].ToString(), sheetType = row["TABLE_TYPE"].ToString(), sheetCatalog = row["TABLE_CATALOG"].ToString(), sheetSchema = row["TABLE_SCHEMA"].ToString() });
            }
        }
        conn.Close();
        return sheetNames;
     }
} 

class SheetName
{
     public string sheetName { get; set; }
     public string sheetType { get; set; }
     public string sheetCatalog { get; set; }
     public string sheetSchema { get; set; }
}

Please get back to me if you're having any kind of issues with this.

Have fun!

like image 125
Catalin Avatar answered Oct 07 '22 01:10

Catalin