Excel "La tabla externa no está en el formato esperado".


162

Estoy tratando de leer un archivo Excel (xlsx) usando el código que se muestra a continuación. Me sale una "tabla externa no está en el formato esperado". error a menos que ya tenga el archivo abierto en Excel. En otras palabras, primero tengo que abrir el archivo en Excel antes de poder leerlo desde mi programa C #. El archivo xlsx está en un recurso compartido en nuestra red. ¿Cómo puedo leer el archivo sin tener que abrirlo primero? Gracias

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);
}

FWIW Recibí esto en una hoja de Excel, cuando intentaba abrirlo, estaba usando el ACE actual y las propiedades extendidas sugeridas. Cuando abrí el archivo manualmente, tenía ese mensaje en la parte superior para habilitar la edición, necesito resolver cómo voltear ese bit automáticamente, pero si está obteniendo esto, es posible que solo necesite abrir el archivo y luego habilitar la edición . Puedo mirar para ver si puedo abrir el archivo de solo lectura, vi algo muy abajo en este hilo sobre eso.
Jeff Patton

Respuestas:


246

"La tabla externa no está en el formato esperado". normalmente ocurre cuando se trata de usar un archivo de Excel 2007 con una cadena de conexión que usa: Microsoft.Jet.OLEDB.4.0 y Extended Properties = Excel 8.0

El uso de la siguiente cadena de conexión parece solucionar la mayoría de los 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;";

10
Irónicamente, recibí este error de la aplicación de otra persona (Scribe), pero la explicación aún resolvió el problema para mí: "Guardar como" Excel 97-2003, y se corrigió el error.
Jeff Davis

44
Extensión .xlsx o .xls?
FAtBalloon

3
es posible que
deba

11
esto puede ser increíble, pero simplemente cambio el nombre de la hoja a minúsculas y uso sheet1 $
Smith

3
Estoy usando LinqToExcel, y para que LinqToExcel use esa cadena de consulta, tengo que cambiar el nombre del archivo a xlsx. La hoja de cálculo en cuestión es realmente una hoja de cálculo de Excel 97, pero al proveedor de odbc no parece importarle eso. Una vez que engaño a LinqToExcel para que use la cadena de consulta correcta, el Proveedor aparentemente determina cómo leer el archivo independientemente de la extensión del archivo. Conveniente escapatoria en mi caso.
Tim Coker el

26

Gracias por este código :) Realmente lo aprecio. Funciona para mi.

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

Entonces, si tiene una versión diff del archivo Excel, obtenga el nombre del archivo, si su extensión es .xlsx , use esto:

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

y si se trata de .xls , utilice:

Private Const connstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" + path + ";Extended Properties=""Excel 8.0;HDR=YES;"""

55
FYI: Esto arrojará una OleDbException si intenta abrir un .xlsarchivo en una PC que no tiene instalado el Jet OleDb.
jp2code

@Trex, ¿estás seguro de que tu última línea de código es correcta? ¿Puedes volver a verificarlo en algún editor nuevamente?
Jogi

15

(Tengo muy poca reputación para comentar, pero este es un comentario sobre la entrada de JoshCaba, usando el motor Ace en lugar de Jet para Excel 2007)

Si no tiene Ace instalado / registrado en su máquina, puede obtenerlo en: https://www.microsoft.com/en-US/download/details.aspx?id=13255

Se aplica también a Excel 2010.


Tengo instalado el motor ACE, pero necesito saber qué referencia II debo incluir en mi proyecto para que mi instalador lo incluya. No todas las máquinas en las que está instalada mi aplicación necesariamente tendrán instalado MS Office.
jp2code

1
El enlace ahora muestra un mensaje de error - We're sorry, this download is no longer available.
RBT

9

Solo agrega mi caso. Mi archivo xls fue creado por una función de exportación de datos desde un sitio web, la extensión del archivo es xls, normalmente puede abrirse con MS Excel 2003. Pero tanto Microsoft.Jet.OLEDB.4.0 como Microsoft.ACE.OLEDB.12.0 obtuvieron un " La tabla externa no está en el formato esperado "excepción.

Finalmente, el problema es, tal como lo dijo la excepción, "no está en el formato esperado". Aunque su nombre de extensión es xls, pero cuando lo abro con un editor de texto, en realidad es un archivo html bien formado, todos los datos están en una <table>, cada <tr> es una fila y cada <td> es un célula. Entonces creo que puedo analizarlo de forma html.


Este también fue mi caso, sin embargo, mi archivo era en realidad un XML. Aún así, sería bueno saber cómo importarlo usando OBDC, pero no creo que sea compatible.
David Rogers

@DavidRogers, alguna vez vi algo como XML ODBC Driver, pero nunca lo usé, eche un vistazo a cdata.com/drivers/xml/odbc .
Joseph Ding

El mismo caso aquí, supongo que la magia comenzó al abrir el archivo con el bloc de notas, de hecho, estoy votando su respuesta porque no me desplacé hacia abajo para ver su publicación hasta ahora (y ahora ya abrí el archivo / lo analicé) con el paquete Html Agility ...) pero tu respuesta merece estar en la parte superior, por pura lógica: ¡ABRE EL ARCHIVO PRIMERO! ¡y mira si tiene algún estilo de archivo Excel-ish dentro!
Gabriel G

Si se trata de un archivo html, simplemente aplique las propiedades extendidas de la siguiente manera:Extended Properties=""HTML Import;HDR=No;IMEX=1
Nepaluz

4

Yo tuve el mismo problema. que tal como se resolvió con estos pasos:

1.) Haga clic en Archivo

2.) Seleccione "guardar como"

3.) Haga clic en el menú desplegable (Guardar como tipo)

ingrese la descripción de la imagen aquí

4.) Seleccione Excel 97-2003 Workbook

ingrese la descripción de la imagen aquí

5.) Haga clic en el botón Guardar

ingrese la descripción de la imagen aquí


1
¡Abucheo! Volver a un formato de archivo desactualizado ni siquiera debería ser una consideración. En el momento de esta respuesta, el formato 97-2003 tenía 16 años y 12 años de antigüedad. Podría entender algunos años, pero más de una década desactualizada no debería sugerirle a un desarrollador profesional que el formato del archivo debe ser anterior.
Lemiarty

3

Tuve este mismo problema (Uso de ACE.OLEDB) y lo que lo resolvió para mí fue este enlace:

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

La esencia de esto es que la instalación de varias versiones de Office y varios SDK, ensamblados, etc. de Office ha llevado a la referencia ACEOleDB.dll en el registro que apunta a la carpeta OFFICE12 en lugar de OFFICE14 en

C: \ Archivos de programa \ Archivos comunes \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

Desde el enlace:

Alternativamente, puede modificar la clave de registro cambiando la ruta dll para que coincida con la de su versión de Access.

Access 2007 debe usar OFFICE12, Access 2010 - OFFICE14 y Access 2013 - OFFICE15

(SO: 64bit Office: 64bit) o ​​(OS: 32bit Office: 32bit)

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

Nombre del valor: (predeterminado)

Datos del valor: C: \ Archivos de programa \ Archivos comunes \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

(SO: 64 bits Oficina: 32 bits)

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

Nombre del valor: (predeterminado)

Datos del valor: C: \ Archivos de programa (x86) \ Archivos comunes \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL


Me resultó más fácil ir a Programas y características y reparar ACE. (Para mí, ACE se llama Microsoft Access Runtime 2016). Supongo que estaba teniendo esta variante del problema y que Repair simplemente restableció todas las claves de registro por mí sin tener que molestarme con regedit ;-).
binki

2

También he visto este error al intentar usar fórmulas complejas INDIRECT () en la hoja que se está importando. Me di cuenta de esto porque esta era la única diferencia entre dos libros de trabajo donde uno importaba y el otro no. Ambos eran archivos 2007+ .XLSX y se instaló el motor 12.0.

Confirmé que este era el problema:

  • Hacer una copia del archivo (todavía tenía el problema, por lo que no era una diferencia de guardar como)
  • Seleccionar todas las celdas en la hoja con las fórmulas indirectas
  • Pegar solo como valores

y el error desapareció


2

Estaba recibiendo errores con terceros y Oledb leyendo un libro de trabajo XLSX. El problema parece ser una hoja de trabajo oculta que causa un error. Mostrar la hoja de trabajo permitió importar el libro de trabajo.


2

Si el archivo es de solo lectura, simplemente elimínelo y debería funcionar nuevamente.


1

Me encontré con el mismo problema y encontré este hilo. Ninguna de las sugerencias anteriores ayudó, excepto el comentario de @ Smith a la respuesta aceptada el 17 de abril de 2013.

El fondo de mi problema está lo suficientemente cerca de @ zhiyazw, básicamente tratando de configurar un archivo Excel exportado (SSRS en mi caso) como la fuente de datos en el paquete dtsx. Todo lo que hice, después de pensar un poco, fue renombrar la hoja de trabajo. No tiene que estar en minúsculas como ha sugerido @Smith.

Supongo que ACE OLEDB espera que el archivo de Excel siga una determinada estructura XML, pero de alguna manera Reporting Services no lo sabe.


Me encontré con el mismo problema de la tabla que no está en el formato esperado. Verifiqué que mi libro no tenía hojas ocultas. El nombre real de la hoja de trabajo en el libro está en mayúscula pero en el código C # para analizar el archivo agregué .ToLower () para el nombre de la pestaña y ahora puedo analizar el archivo de Excel nuevamente. ¡GRACIAS!
vvvv4d

1

Esa dirección de archivo de Excel puede tener una extensión incorrecta. Puede cambiar la extensión de xls a xlsx o viceversa e intentar nuevamente.




0

Solo agrego mi solución a este problema. Estaba cargando un archivo .xlsx en el servidor web, luego leía e insertaba en masa en SQL Server. Recibía el mismo mensaje de error, probé todas las respuestas sugeridas pero ninguna funcionó. Finalmente, guardé el archivo como Excel 97-2003 (.xls) que funcionó ... el único problema que tengo ahora es que el archivo original tenía más de 110,000 filas.


0

Si todavía tiene este problema, compruebe sus permisos, probé muchas de estas sugerencias y mi problema concreto fue que el archivo que quería procesar estaba bajo control de origen y el hilo no tenía permisos, tuve que cambiar todos los permisos de la carpeta y comenzó a funcionar (estaba procesando muchos archivos allí) ... También coincide con muchas sugerencias, como cambiar el nombre del archivo o verificar que el archivo no esté bloqueado por otro proceso.

Espero que te ayude.


0

Tuve este problema y el cambio de Propiedades extendidas a Importación HTML lo solucionó según esta publicación de Marcus Miris:

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

0

En lugar de OleDb, puede usar la Interoperabilidad de Excel y abrir la hoja de trabajo como solo lectura.

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


55
La interoperabilidad de Excel no es un método recomendado para trabajar con Excel. Puede causar muchos problemas y, por lo tanto, no debe recomendarse.
MaxOvrdrv

Aunque esta es una publicación antigua, estoy de acuerdo con MaxOvrdrv, usar la interoperabilidad no es una buena idea y debe evitarse, si no es por otra razón que requiere una instalación completa de Excel en el servidor.
Lemiarty

Absolutamente no deberías hacer esto.
sovemp

0

ACE ha reemplazado a JET

Ace admite todas las versiones anteriores de Office

¡Este código funciona bien!

        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();

1
No es asi. El problema aún puede ocurrir, aún no he descubierto por qué, dado que todos mis archivos son de Excel 2007, y algunos de ellos funcionan, otros no.
Henrik

¿Tiene una fuente para ese reclamo? No me conozco, solo me pregunto. :-)
midoriha_senpai

0

Esto puede ocurrir cuando el libro de trabajo está protegido con contraseña. Existen algunas soluciones para eliminar esta protección, pero la mayoría de los ejemplos que encontrará en línea no están actualizados. De cualquier manera, la solución simple es desproteger el libro de trabajo manualmente, de lo contrario, use algo como OpenXML para eliminar la protección mediante programación.


0

Recientemente vi este error en un contexto que no coincidía con ninguna de las respuestas enumeradas anteriormente. Resultó ser un conflicto con AutoVer . Solución alternativa: deshabilite temporalmente AutoVer.


0

Recientemente tuve este "System.Data.OleDb.OleDbException (0x80004005): la tabla externa no está en el formato esperado". se produce un error Estaba confiando en Microsoft Access 2010 Runtime. Antes de la actualización que se instaló automáticamente en mi servidor el 12 de diciembre de 2018, mi código C # funcionó bien con el proveedor Microsoft.ACE.OLEDB.12.0. Después de instalar la actualización del 12 de diciembre de 2018, comencé a obtener la "Tabla externa no está en el formato esperado" en mi archivo de registro.

Abandoné el tiempo de ejecución de Microsoft Access 2010 e instalé el tiempo de ejecución de Microsoft Access 2013 y mi código C # comenzó a funcionar nuevamente sin "System.Data.OleDb.OleDbException (0x80004005): la tabla externa no está en el formato esperado". errores

Versión de 2013 que solucionó este error para mí https://www.microsoft.com/en-us/download/confirmation.aspx?id=39358

Versión de 2010 que funcionó para mí antes de la actualización que se instaló automáticamente en mi servidor el 12 de diciembre. https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

También tuve este error el mes pasado en un proceso automatizado. El código C # funcionó bien cuando lo ejecuté depurando. Descubrí que la cuenta de servicio que ejecuta el código también necesitaba permisos para la carpeta C: \ Windows \ Temp.


0

Mi alcance consiste en la descarga de la plantilla y verifica la plantilla cuando está llena de datos.

1) Descargue un archivo de plantilla (.xlsx) con la fila del encabezado. el archivo se genera usando openxml y funciona perfectamente.

2) Cargue el mismo archivo sin ningún cambio desde su estado descargado. Esto provocará un error de conexión y falla (la conexión OLEDB se está utilizando para leer la hoja de Excel).

Aquí, si se llenan los datos, el programa funciona como se esperaba.

Cualquiera que tenga una idea del problema está conectado con el archivo que estamos creando, está en formato xml si lo abrimos y simplemente lo guardamos, lo convertimos a formato Excel y funciona bien.

¿Alguna idea para descargar Excel con el tipo de archivo preferido?


no debe hacer preguntas en sus respuestas, si necesita respuestas a su pregunta, pregúntelas por separado si es necesario.
Abhishek Garg

0

Trabajando con un código anterior y encontré esta misma excepción genérica. Es muy difícil rastrear el problema, así que pensé en agregarlo aquí en caso de que ayude a alguien más.

En mi caso, había código en otra parte del proyecto que estaba abriendo un StreamReader en el archivo de Excel antes de que OleDbConnection intentara abrir el archivo (esto se hizo en una clase base).

Básicamente, solo necesitaba llamar Close()primero al objeto StreamReader, luego podría abrir la conexión OleDb con éxito. No tenía nada que ver con el archivo de Excel en sí, ni con la cadena OleDbConnection (que es, naturalmente, donde estaba mirando al principio).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.