Obtendo a primeira folha de um documento Excel independentemente do nome da folha com OleDb
Pergunta
Eu tenho usuários que nomeiam suas folhas de todos os tipos de coisas loucas, mas eu quero ser capaz de obter a primeira folha do documento Excel independentemente do que ele é chamado.
Eu uso atualmente:
OleDbDataAdapter adapter = new OleDbDataAdapter(
"SELECT * FROM [sheetName$]", connString);
Como eu iria sobre a obtenção da primeira folha não importa o que é chamado?
Obrigado.
Solução
acabou usando o seguinte:
using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
Sheet1= dtSchema.Rows[0].Field<string>("TABLE_NAME");
}
Outras dicas
OleDbConnection oconn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="Path"; Extended Properties=Excel 12.0;Persist Security Info=False;");
oconn.Open();
myCommand.Connection = oconn;
DataTable dbSchema = oconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dbSchema == null || dbSchema.Rows.Count < 1)
{
throw new Exception("Error: Could not determine the name of the first worksheet.");
}
string firstSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString();
Este código tem trabalhado muito bem onde eu tenho usado a grade de dados "DataGridView1" para carregar todo o conteúdo da folha
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet : Dim filteext As String = ""
''check for the file type
If IO.Path.GetExtension(fileName) = "xls" Then
filteext = "Excel 8.0"
ElseIf IO.Path.GetExtension(fileName) = ".xlsx" Then
filteext = "Excel 12.0"
End If
''open connection
MyConnection = New System.Data.OleDb.OleDbConnection _
("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & fileName & "';Extended Properties=" & filteext & ";")
MyConnection.Open()
Dim myTableName = MyConnection.GetSchema("Tables").Rows(0)("TABLE_NAME")
Dim MyCommand As OleDbDataAdapter = New OleDbDataAdapter(String.Format("SELECT * FROM [{0}]", myTableName), MyConnection)
MyCommand.TableMappings.Add("Table", "TestTable")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
DataGridView1.DataSource = DtSet.Tables(0)
'DtSet.DataSetName.
MyConnection.Close()
Você pode usar o GetOleDbSchemaTable (VB) ou GetOleDbSchemaTable (C #).
Usando as Tabelas Enum ele irá retornar uma lista de todos os nomes de planilha, que você pode usar para construir dinamicamente o SQL necessário.
Você pode usar:
MySchemaTable = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
Todos os nomes Planilhas serão devolvidos como parte de um DataTable que você pode-los itterate completamente.
Usando a informação OleDbSchemaGuid pode ser recuperada no
- Colunas
- As chaves estrangeiras
- Índices
- As chaves primárias
- Tabelas
- Visualizações
completa MSDN documentação disponível aqui
Basicamente uma cópia da resposta de Anirudh Gaur. Eu fiz alguma reformatação do código e colocá-lo em uma função. Eu adicionei um StringBuilder para que eu possa fazer mais com a instrução SELECT.
Upvotes ir para Anirudh Gaur
Private Function Load_XLS(FileName As String) As DataTable
Dim DataTable As New DataTable
Dim Format As String = ""
If IO.Path.GetExtension(FileName) = ".xls" Then
Format = "Excel 8.0"
ElseIf IO.Path.GetExtension(FileName) = ".xlsx" Then
Format = "Excel 12.0"
End If
Using Connection As New OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & FileName & "';Extended Properties=" & Format & ";")
Connection.Open()
Dim TableName As String = Connection.GetSchema("Tables").Rows(0)("TABLE_NAME")
Dim SQLCommand As New Text.StringBuilder
SQLCommand.AppendLine("SELECT *")
SQLCommand.AppendLine("FROM [{0}]")
Dim Command As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(String.Format(SQLCommand.ToString, TableName), Connection)
Command.Fill(DataTable)
Connection.Close()
End Using
Return DataTable
End Function
It`s minha solução ? (Easy, Fast, executável, Compreensível)
internal static DataTable GetExcelSheet(string excelFile,string sheetName = "")
{
string fullPathToExcel = Path.GetFullPath(excelFile);
string connString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel " + (excelFile.ToLower().EndsWith("x") ? "12.0" : "8.0") + ";HDR=yes'", fullPathToExcel);
return GetDataTable(connString, "SELECT * FROM [" + (string.IsNullOrEmpty(sheetName) ? GetTableName(connString, 0) : sheetName + "$") + "]");
}
private static DataTable GetDataTable(string connectionString, string sql)
{
DataTable dt = new DataTable();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
{
using (OleDbDataReader rdr = cmd.ExecuteReader())
{
dt.Load(rdr);
return dt;
}
}
}
}
private static string GetTableName(string connectionString, int row = 0)
{
OleDbConnection conn = new OleDbConnection(connectionString);
try
{
conn.Open();
return conn.GetSchema("Tables").Rows[row]["TABLE_NAME"] + "";
}
catch { }
finally { conn.Close();}
return "sheet1";
}
Você pode usar esta abordagem também para obter o nome folha. Veja os comentários para mais compreensão
myExcelConn.Open()
//GET DATA FROM EXCEL SHEET.
Dim str As String = String.Empty
Dim Sheets As DataTable = myExcelConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
For i As Integer = 0 To Sheets.Rows.Count - 1
str += Sheets.Rows(i)("TABLE_NAME").ToString() + "," //It will return sheet1,sheet2,sheet3 according to my excel file
Next
Dim objOleDB As New OleDbCommand("SELECT *FROM [" + str.Split(",")(0) + "]", myExcelConn) //It will select sheet1
Me.Label1.Text = str.Split(",")(0).Replace("$", "")
// READ THE DATA EXTRACTED FROM THE EXCEL FILE.
Dim objBulkReader As OleDbDataReader
objBulkReader = objOleDB.ExecuteReader
Dim dt As DataTable = New DataTable
dt.Load(objBulkReader)
//FINALLY, BIND THE EXTRACTED DATA TO THE GRIDVIEW.
GridView1.DataSource = dt
GridView1.DataBind()
//If you want sheet2 data
Dim objOleDB1 As New OleDbCommand("SELECT *FROM [" + str.Split(",")(1).Split(",")(0) + "]", myExcelConn)
//If you want sheet3 data
Dim objOleDB2 As New OleDbCommand("SELECT *FROM [" + str.Split(",")(2).Split(",")(0) + "]", myExcelConn)
Você pode obter o nome sheet1 como este e uso neste manner.If você deseja obter outros nomes de folha você pode aumentar o valor de 0,1,2 ..
Dim myExcelConn As OleDbConnection = _
New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
Server.MapPath(".") & "\" & FileUpload1.FileName() & _
";Extended Properties=Excel 12.0;")
Dim Sheets As DataTable = myExcelConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
Sheet1 = Sheets.Rows(0)("TABLE_NAME").ToString()
Dim objOleDB As New OleDbCommand("SELECT *FROM [" + Sheet1 + "]", myExcelConn)