tutorial read open for data create c# .net excel oledb

c# - read - Notación científica al importar desde Excel en.Net



read xls c# oledb (10)

¿Has intentado convertir el valor del campo en (int) o quizás (Int64) mientras lo estás leyendo?

Tengo un trabajo en C # / .Net que importa datos de Excel y luego los procesa. Nuestro cliente entrega los archivos y los procesamos (importante porque no tengo ningún control sobre el archivo original).

Uso la biblioteca OleDb para completar un conjunto de datos (odio escribir ese código. En serio, ¿hay algún código que un desarrollador .Net teme escribiendo más que eso?). El archivo contiene algunos números como 30829300, 30071500, etc. El tipo de datos para esas columnas es "Texto".

Esos números se convierten a notación científica cuando importo los datos. ¿Hay alguna forma de evitar que esto suceda?

-Chris


Descubrí que la forma más fácil es elegir el formato Zip, en lugar del formato de texto para las columnas con grandes "números".


La biblioteca OleDb, en la mayoría de los casos, estropeará sus datos en una hoja de cálculo de Excel. Esto se debe en gran medida a que obliga a todo a un diseño de columna de tipo fijo, adivinando el tipo de columna de los valores en las primeras 8 celdas de cada columna. Si adivina mal, terminas con cadenas de dígitos convertidas a notación científica. ¡Blech!

Para evitar esto, es mejor evitar el OleDb y leer la hoja directamente usted mismo. Puede hacerlo utilizando la interfaz COM de Excel (¡también blech!) O un lector compatible con .NET Excel de terceros. SpreadsheetGear es una de esas bibliotecas que funciona razonablemente bien y tiene una interfaz muy similar a la interfaz COM de Excel.


Busque la opción de cadena de conexión IMEX = 1 y la configuración de registro TypeGuessRows en google. En verdad, no hay una manera fácil de evitar esto porque el lector infiere los tipos de datos de columna mirando las primeras filas (8 por defecto). Si las filas contienen todos los números, no tiene suerte.

Una solución desafortunada que he utilizado en el pasado es utilizar la opción de cadena de conexión HDR = NO y establecer el valor de configuración de registro TypeGuessRows en 1, lo que obliga a leer la primera fila como datos válidos para hacer su determinación de tipo de datos, en lugar de un encabezado. Es un truco, pero funciona. El código lee la primera fila (que contiene el encabezado) como texto, y luego establece el tipo de datos en consecuencia.

Cambiar el registro es una molestia (y no siempre es posible), pero recomiendo restaurar el valor original después.

Si sus datos de importación no tienen una fila de encabezado, entonces una opción alternativa es preprocesar el archivo e insertar un ''carácter antes de cada uno de los números en la columna infractora. Esto hace que los datos de columna se traten como texto.

Así que en general, hay muchos hacks para solucionar esto, pero nada realmente infalible.


Tuve el mismo problema, pero pude solucionarlo sin recurrir a la interfaz COM de Excel o software de terceros. Implica un poco de procesamiento, pero parece estar funcionando para mí.

  1. Primero lea en los datos para obtener los nombres de las columnas
  2. Luego, cree un nuevo DataSet con cada una de estas columnas, configurando cada uno de sus DataTypes en string.
  3. Lee los datos de nuevo en este nuevo conjunto de datos. Voila: la notación científica ya no existe y todo se lee como una cadena.

Aquí hay un código que ilustra esto, y como un bono adicional, ¡es incluso StyleCopped!

public void ImportSpreadsheet(string path) { string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1"; string connectionString = string.Format( CultureInfo.CurrentCulture, "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=/"{1}/"", path, extendedProperties); using (OleDbConnection connection = new OleDbConnection(connectionString)) { using (OleDbCommand command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM [Worksheet1$]"; connection.Open(); using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) using (DataSet columnDataSet = new DataSet()) using (DataSet dataSet = new DataSet()) { columnDataSet.Locale = CultureInfo.CurrentCulture; adapter.Fill(columnDataSet); if (columnDataSet.Tables.Count == 1) { var worksheet = columnDataSet.Tables[0]; // Now that we have a valid worksheet read in, with column names, we can create a // new DataSet with a table that has preset columns that are all of type string. // This fixes a problem where the OLEDB provider is trying to guess the data types // of the cells and strange data appears, such as scientific notation on some cells. dataSet.Tables.Add("WorksheetData"); DataTable tempTable = dataSet.Tables[0]; foreach (DataColumn column in worksheet.Columns) { tempTable.Columns.Add(column.ColumnName, typeof(string)); } adapter.Fill(dataSet, "WorksheetData"); if (dataSet.Tables.Count == 1) { worksheet = dataSet.Tables[0]; foreach (var row in worksheet.Rows) { // TODO: Consume some data. } } } } } } }


Busqué en Google este estado ... Aquí están mis pasos de solificación

  • Para el archivo excel de la plantilla

Columna de Excel de 1 formato como macro Texto 2- escribir para deshabilitar advertencias de error para Número -> conversión de texto

Private Sub Workbook_BeforeClose(Cancel As Boolean) Application.ErrorCheckingOptions.BackgroundChecking = Ture End Sub Private Sub Workbook_Open() Application.ErrorCheckingOptions.BackgroundChecking = False End Sub

  • En código subyacente

3- mientras lee datos para importar, intente analizar los datos entrantes a Int64 o Int32 ....


Estoy interesado en saber si alguien obtuvo una respuesta a esto. He estado subiendo y bajando por los interwebs e intenté todas las combinaciones de IMEX y HDR. IMEX = 1 es el único con el que logré extraer los valores de fecha, moneda y número general. Pero los grandes números aún se muestran como científicos. Solo necesito leer archivos y cambiar hojas de cálculo, registro, terceros no es una opción.


Una solución a este problema es cambiar su declaración de selección, en lugar de SELECT * hacer esto:

"SELECT Format([F1], ''General Number'') From [Sheet1$]" -or- "SELECT Format([F1], /"#####/") From [Sheet1$]"

Sin embargo, si lo hace explotará si sus celdas contienen más de 255 caracteres con el siguiente error: "OLE DB de varios pasos generó errores. Revise cada valor de estado de OLE DB, si está disponible. No se realizó ningún trabajo".

Afortunadamente, a mi cliente no le importó el error en este escenario.

Esta página también tiene muchas cosas buenas que probar: http://www.dicks-blog.com/archives/2004/06/03/external-data-mixed-data-types/


Si observa el archivo .XSLX real utilizando Open XML SDK 2.0 Productivity Tool (o simplemente descomprime el archivo y ve el XML en el bloc de notas) verá que Excel 2007 en realidad almacena los datos sin procesar en formato científico.

Por ejemplo 0.00001 se almacena como 1.0000000000000001E-5

<x:c r="C18" s="11" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <x:v>1.0000000000000001E-5</x:v> </x:c>

Al mirar la celda en Excel se muestra como 0.00001 tanto en la celda como en la barra de fórmulas. Por lo tanto, no siempre es cierto que OleDB está causando el problema.


Usando esta cadena de conexión:

Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=/"Excel 12.0;HDR=NO;IMEX=1/"

con Excel 2010 he notado lo siguiente. Si el archivo de Excel está abierto cuando ejecuta OLEDB SELECT, obtendrá la versión actual de las celdas, no los valores guardados del archivo. Además, los valores de cadena devueltos para un número largo, un valor decimal y una fecha se ven así:

5.0130370071e+012 4.08 36808

Si el archivo no está abierto, los valores devueltos son:

5013037007084 £4.08 Monday, October 09, 2000