Excel "Tabela externa não está no formato esperado".

162

Estou tentando ler um arquivo do Excel (xlsx) usando o código mostrado abaixo. Eu recebo uma "tabela externa não está no formato esperado". erro, a menos que eu já tenha o arquivo aberto no Excel. Em outras palavras, eu tenho que abrir o arquivo no Excel primeiro antes de poder ler se do meu programa C #. O arquivo xlsx está em um compartilhamento em nossa rede. Como posso ler o arquivo sem precisar abri-lo primeiro? obrigado

string sql = "SELECT * FROM [Sheet1$]";
string excelConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathname + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"";

using (OleDbDataAdapter adaptor = new OleDbDataAdapter(sql, excelConnection)) {
    DataSet ds = new DataSet();
    adaptor.Fill(ds);
}
Sisiutl
fonte
FWIW Recebi isso em uma planilha do Excel. Ao tentar abri-lo, estava usando o ACE atual e as propriedades estendidas sugeridas. Quando abri o arquivo manualmente, ele tinha o prompt na parte superior para ativar a edição, preciso resolver como virar esse bit automaticamente, mas se você estiver obtendo isso, talvez seja necessário abrir o arquivo e ativar a edição . Posso olhar para ver se consigo abrir o arquivo somente leitura, vi algo muito distante neste tópico sobre isso.
Jeff Patton

Respostas:

246

"A tabela externa não está no formato esperado." geralmente ocorre ao tentar usar um arquivo do Excel 2007 com uma cadeia de conexão que usa: Microsoft.Jet.OLEDB.4.0 e Propriedades estendidas = Excel 8.0

O uso da seguinte cadeia de conexão parece corrigir a maioria dos problemas.

public static string path = @"C:\src\RedirectApplication\RedirectApplication\301s.xlsx";
public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
FAtBalloon
fonte
10
Ironicamente, recebi esse erro do aplicativo de outra pessoa (Scribe), mas a explicação ainda resolveu o problema para mim: "Salvar como" Excel 97-2003, e o erro foi corrigido.
Jeff Davis
4
Extensão .xlsx ou .xls?
FAtBalloon
3
pode ser necessário instalar o primeiro: microsoft.com/en-us/download/confirmation.aspx?id=23734
rovsen
11
isso pode ser inacreditável, mas eu simplesmente altero o nome da planilha para todas as minúsculas e uso sheet1 $
Smith
3
Estou usando o LinqToExcel e, para que o LinqToExcel use essa string de consulta, preciso renomear o arquivo para xlsx. A planilha em questão realmente é uma planilha do Excel 97, mas o provedor ODBC não parece se importar com isso. Depois de induzir o LinqToExcel a usar a string de consulta correta, o Provedor aparentemente determina como ler o arquivo independentemente da extensão do arquivo. Fenda conveniente no meu caso.
Tim Coker
26

Obrigado por este código :) Eu realmente aprecio isso. Funciona para mim.

public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

Portanto, se você possui a versão diff do arquivo do Excel, obtenha o nome do arquivo, se a extensão for .xlsx , use o seguinte:

Private Const connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

e se for .xls , use:

Private Const connstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" + path + ";Extended Properties=""Excel 8.0;HDR=YES;"""
Trex
fonte
5
FYI: Isso lançará uma OleDbException se você tentar abrir um .xlsarquivo em um PC que não tenha o Jet OleDb instalado.
jp2code
@Trex, você tem certeza de que sua última linha de código está correta? Você pode verificar novamente em algum editor novamente?
Jogi
15

(Tenho reputação muito baixa para comentar, mas isso é comentário sobre a entrada de JoshCaba, usando o mecanismo Ace em vez do Jet for Excel 2007)

Se você não tem o Ace instalado / registrado em sua máquina, pode obtê-lo em: https://www.microsoft.com/en-US/download/details.aspx?id=13255

Também se aplica ao Excel 2010.

cederlof
fonte
Eu tenho o mecanismo ACE instalado, mas preciso saber qual referência II precisa incluir no meu projeto para que meu instalador o inclua. Nem todas as máquinas em que meu aplicativo está instalado terão necessariamente o MS Office instalado.
Jp2code
1
O link agora exibe uma mensagem de erro - We're sorry, this download is no longer available.
RBT
9

Apenas adicione meu caso. Meu arquivo xls foi criado por uma função de exportação de dados de um site, a extensão do arquivo é xls, normalmente pode ser aberta pelo MS Excel 2003. Mas o Microsoft.Jet.OLEDB.4.0 e o Microsoft.ACE.OLEDB.12.0 obtiveram um " A tabela externa não está no formato esperado "exceção.

Por fim, o problema é, assim como a exceção disse, "não está no formato esperado". Embora o nome da extensão seja xls, mas quando eu o abro com um editor de texto, na verdade é um arquivo html bem formado, todos os dados estão em uma <table>, cada <tr> é uma linha e cada <td> é um célula. Então eu acho que posso analisá-lo de uma maneira html.

Joseph Ding
fonte
Este também foi o meu caso, no entanto, meu arquivo era na verdade um XML. Ainda assim, seria bom saber como importá-lo usando o OBDC, mas não acho que seja suportado.
David Rogers
@ DavidRogers, eu já vi algo como XML ODBC Driver, mas nunca usei, você pode ver cdata.com/drivers/xml/odbc .
Joseph Ding
Mesmo caso aqui, acho que a mágica começou na abertura do arquivo com o bloco de notas; na verdade, estou votando sua resposta porque não rolei para baixo para ver sua postagem até agora (e agora eu já abri o arquivo / o analisei com o pacote Html Agility ...), mas sua resposta merece estar no topo, por pura lógica: ABRA O ARQUIVO PRIMEIRO! e veja se tem algum estilo de arquivo Excel-ish dentro!
Gabriel G
Se for um arquivo html, basta aplicar as propriedades estendidas assim:Extended Properties=""HTML Import;HDR=No;IMEX=1
Nepaluz
4

Eu tive o mesmo problema. que foi resolvido usando estas etapas:

1.) Clique em Arquivo

2.) Selecione "salvar como"

3.) Clique no menu suspenso (Salvar como tipo)

insira a descrição da imagem aqui

4.) Selecione Pasta de trabalho do Excel 97-2003

insira a descrição da imagem aqui

5.) Clique no botão Salvar

insira a descrição da imagem aqui

Kamran
fonte
1
Vaia! A reversão para um formato de arquivo desatualizado não deve ser considerado. No momento desta resposta, o formato 97-2003 tinha 16 anos e 12 anos desatualizados. Eu pude entender alguns anos, mas mais de uma década desatualizada não deve sugerir a um desenvolvedor profissional que o formato do arquivo precisa ser mais antigo.
Lemiarty 17/04
3

Eu tive esse mesmo problema (usando o ACE.OLEDB) e o que resolveu para mim foi este link:

http://support.microsoft.com/kb/2459087

O essencial é que a instalação de várias versões do Office e vários sdks, assemblies etc. do escritório levou à referência ACEOleDB.dll no registro, apontando para a pasta OFFICE12 em vez do OFFICE14 em

C: \ Arquivos de Programas \ Arquivos Comuns \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

No link:

Como alternativa, você pode modificar a chave do Registro alterando o caminho da DLL para corresponder ao da sua versão do Access.

O Access 2007 deve usar o OFFICE12, o Access 2010 - OFFICE14 e o Access 2013 - OFFICE15

(SO: escritório de 64 bits: 64 bits) ou (SO: escritório de 32 bits: 32 bits)

Chave: HKCR \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Nome do valor: (Padrão)

Dados do valor: C: \ Arquivos de Programas \ Arquivos Comuns \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

(SO: escritório de 64 bits: 32 bits)

Chave: HKCR \ Wow6432Node \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Nome do valor: (Padrão)

Dados do valor: C: \ Arquivos de Programas (x86) \ Arquivos Comuns \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

jordanhill123
fonte
Achei mais fácil ir para Programas e Recursos e Reparar o ACE. (Para mim, o ACE é chamado Microsoft Access Runtime 2016). Presumo que eu estava tendo essa variante do problema e que o Reparo acabou de redefinir todas as chaves de registro para mim sem que eu tivesse que me preocupar com o regedit ;-).
binki
2

Também vi esse erro ao tentar usar fórmulas complexas INDIRECT () na planilha que está sendo importada. Percebi isso porque essa era a única diferença entre duas pastas de trabalho em que uma estava importando e a outra não. Ambos tinham mais de 2007 arquivos .XLSX e o mecanismo 12.0 foi instalado.

Confirmei que esse era o problema:

  • Fazendo uma cópia do arquivo (ainda havia o problema, não havia diferença entre salvar como)
  • Selecionando todas as células na planilha com as fórmulas indiretas
  • Colar apenas como valores

e o erro desapareceu.

John M. Black
fonte
2

Eu estava recebendo erros com a leitura de uma pasta de trabalho XLSX e de Oledb de terceiros. O problema parece ser uma planilha oculta que causa um erro. Mostrar novamente a planilha permitiu a importação da pasta de trabalho.

John M
fonte
2

Se o arquivo for somente leitura, remova-o e ele deverá funcionar novamente.

Tehscript
fonte
1

Ocorreu o mesmo problema e encontrou este tópico. Nenhuma das sugestões acima ajudou, exceto o comentário de @ Smith à resposta aceita em 17 de abril de 13.

O pano de fundo do meu problema está próximo o suficiente do @ zhiyazw's - basicamente tentando definir um arquivo do Excel exportado (SSRS no meu caso) como fonte de dados no pacote dtsx. Tudo o que fiz, depois de alguns ajustes, foi renomear a planilha. Não precisa ser minúsculo, como o @Smith sugeriu.

Suponho que o ACE OLEDB espera que o arquivo do Excel siga uma certa estrutura XML, mas de alguma forma o Reporting Services não está ciente disso.

kerwei
fonte
Corri para o mesmo problema da tabela não no formato esperado. Eu verifiquei que minha pasta de trabalho não tinha folhas ocultas. O nome da planilha real na pasta de trabalho está em maiúscula, mas no código C # para analisar o arquivo que eu adicionei .ToLower () para o nome da guia e agora posso analisar o arquivo do Excel novamente. OBRIGADO!
vvvv4d
1

Esse endereço de arquivo do Excel pode ter uma extensão incorreta. Você pode alterar a extensão de xls para xlsx ou vice-versa e tente novamente.

Mohammad Fathi MiMFa
fonte
0

o arquivo pode estar bloqueado por outro processo, você precisa copiá-lo e carregá-lo, como diz nesta postagem

user3140982
fonte
0

Apenas adicionando minha solução a esse problema. Eu estava carregando um arquivo .xlsx no servidor da Web, depois lendo e inserindo em massa no SQL Server. Estava recebendo a mesma mensagem de erro, tentei todas as respostas sugeridas, mas nenhuma funcionou. Eventualmente, salvei o arquivo como excel 97-2003 (.xls), que funcionou ... o único problema que tenho agora é que o arquivo original tinha mais de 110.000 linhas.

Kieran Quinn
fonte
0

Se você ainda tiver esse problema, verifique suas permissões, tentei muitas dessas sugestões e meu problema concreto era que o arquivo que eu queria processar estava sob controle de origem e o thread não tinha permissões, tive que alterar as permissões da pasta inteira e começou a funcionar (eu estava processando muitos arquivos lá) ... Ele também corresponde a muitas sugestões, como alterar o nome do arquivo ou verificar se o arquivo não foi bloqueado por outro processo.

Espero que ajude você.

Juan
fonte
0

Eu tive esse problema e alterar as propriedades estendidas para importação de HTML corrigiu-o conforme esta postagem de Marcus Miris:

strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & importedFilePathAndName _
         & ";Extended Properties=""HTML Import;HDR=No;IMEX=1"";"
majjam
fonte
0

Em vez de OleDb, você pode usar a interoperabilidade do Excel e abrir a planilha como somente leitura.

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.open(v=office.15).aspx

Nelson
fonte
5
A interoperabilidade do Excel não é um método recomendado para trabalhar com o Excel. Isso pode causar muitos problemas e, portanto, não deve ser recomendado.
MaxOvrdrv
Embora este seja um post antigo, concordo com o MaxOvrdrv, o uso de interoperabilidade não é uma boa idéia e deve ser evitado, se por nenhum outro motivo, exigir uma instalação completa do Excel no servidor.
Lemiarty
Você absolutamente não deve fazer isso.
sovemp
0

O ACE substituiu o JET

Ace suporta todas as versões anteriores do Office

Este código funciona bem!

        OleDbConnection MyConnection;
        DataSet DtSet;
        OleDbDataAdapter MyCommand;
        
        MyConnection = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\\Book.xlsx;Extended Properties=Excel 12.0;");
        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
        DtSet = new System.Data.DataSet();
        
        MyCommand.Fill(DtSet);
        dataGridView1.DataSource = DtSet.Tables[0];
        MyConnection.Close();
Akshay Upadhyay
fonte
1
Isso não. O problema ainda pode ocorrer, ainda não descobri o motivo, pois meus arquivos são todos do Excel 2007, e alguns deles funcionam, outros não.
27517 Henrik
Você tem uma fonte para essa reivindicação? Eu não me conheço, apenas me perguntando. :-)
midoriha_senpai 11/01
0

Isso pode ocorrer quando a pasta de trabalho está protegida por senha. Existem algumas soluções alternativas para remover essa proteção, mas a maioria dos exemplos que você encontrará online está desatualizada. De qualquer maneira, a solução simples é desproteger a pasta de trabalho manualmente, caso contrário, use algo como o OpenXML para remover a proteção programaticamente.

KthProg
fonte
0

Vi recentemente esse erro em um contexto que não correspondia a nenhuma das respostas listadas anteriormente. Acabou sendo um conflito com o AutoVer . Solução alternativa: desative temporariamente o AutoVer.

desobstruir
fonte
0

Recentemente, tive este "System.Data.OleDb.OleDbException (0x80004005): tabela externa não está no formato esperado." ocorrer um erro. Eu estava contando com o Microsoft Access 2010 Runtime. Antes da atualização que foi instalada automaticamente no meu servidor em 12 de dezembro de 2018, meu código C # funcionou bem usando o provedor Microsoft.ACE.OLEDB.12.0. Após a instalação da atualização de 12 de dezembro de 2018, comecei a obter a tabela "A tabela externa não está no formato esperado" no meu arquivo de log.

Abaixei o tempo de execução do Microsoft Access 2010 e instalei o tempo de execução do Microsoft Access 2013 e meu código C # começou a funcionar novamente sem "System.Data.OleDb.OleDbException (0x80004005): tabela externa não está no formato esperado." erros.

Versão 2013 que corrigiu esse erro para mim https://www.microsoft.com/en-us/download/confirmation.aspx?id=39358

Versão 2010 que funcionou para mim antes da atualização que foi instalada automaticamente no meu servidor em 12 de dezembro. https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

Eu também tive esse erro no mês passado em um processo automatizado. O código C # funcionou bem quando eu executei a depuração. Descobri que a conta de serviço que executava o código também precisava de permissões para a pasta C: \ Windows \ Temp.

vvvv4d
fonte
0

Meu escopo consiste no download do modelo e verifica o modelo quando é preenchido com dados. Portanto,

1) Faça o download de um arquivo de modelo (.xlsx) com a linha do cabeçalho. o arquivo é gerado usando openxml e está funcionando perfeitamente.

2) Carregue o mesmo arquivo sem nenhuma alteração no estado baixado. Isso causará um erro de conexão e falhará (a conexão OLEDB está sendo usada para ler a planilha do Excel).

Aqui, se os dados forem preenchidos, o programa funcionará conforme o esperado.

Qualquer pessoa que tenha uma ideia de que o problema está conectado ao arquivo que estamos criando, está em xml formato , se o abrirmos e salvarmos, convertê-lo para o formato Excel e funcionar bem.

Alguma idéia para baixar o excel com o tipo de arquivo preferido?

Thomson Kattingal
fonte
você não deve fazer perguntas em suas respostas, se precisar de respostas para sua pergunta, faça-as separadamente, se necessário.
Abhishek Garg
0

Trabalhando com algum código mais antigo e encontrei essa mesma exceção genérica. Muito difícil rastrear o problema, então pensei em adicionar aqui caso isso ajude outra pessoa.

No meu caso, havia código em outro lugar do projeto que estava abrindo um StreamReader no arquivo do Excel antes o OleDbConnection tentasse abrir o arquivo (isso foi feito em uma classe base).

Então, basicamente, eu só precisava chamar Close()o objeto StreamReader primeiro, para poder abrir a Conexão OleDb com êxito. Não tinha nada a ver com o próprio arquivo do Excel ou com a string OleDbConnection (que é naturalmente onde eu estava olhando primeiro).

tbone
fonte