Pergunta

Eu tenho um C # /. Líquida de emprego que importa dados do Excel e, em seguida, processa. Nosso cliente cai os arquivos e processá-los (importante porque eu não tenho nenhum controle sobre o arquivo original).

Eu uso a biblioteca OleDb a encher-se um conjunto de dados (eu odeio escrever esse código. Sério, não há qualquer código que um .NET dreads desenvolvedor escrever mais do que isso?). O arquivo contém alguns números como 30829300, 30071500, etc ... O tipo de dados para essas colunas é "Texto".

Esses números são convertidos em notação científica quando eu importar os dados. Existe uma maneira de impedir que isso aconteça?

-Chris

Foi útil?

Solução

A biblioteca OleDb , na maioria das vezes, atrapalhar seus dados em uma planilha do Excel. Isto é principalmente porque força tudo em um layout de coluna do tipo fixo, adivinhação para o tipo de cada coluna a partir dos valores nos primeiros 8 células em cada coluna. Se uma suposição errada, você acaba com seqüências de dígitos convertidos em científica notação. Blech!

Para evitar isso é melhor pular o OleDb e ler a folha directamente a si mesmo. Você pode fazer isso usando a interface COM do Excel (também Blech!), Ou um terceiro .NET Excel compatível leitor. SpreadsheetGear é um tal biblioteca que funciona razoavelmente bem, e tem uma interface que é muito semelhante à interface COM do Excel.

Outras dicas

Uma solução para este problema é mudar sua instrução select, em vez de SELECT * fazer isso:

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

No entanto, isso vai explodir se as células contêm mais de 255 caracteres com o seguinte erro: "De várias etapas operação OLE DB gerou erros. Verifique cada valor de status do OLE DB, se disponível. Nenhum trabalho foi feito."

Felizmente meu cliente não se preocupa com erroring neste cenário.

Esta página tem um monte de coisas boas para tentar assim: http: //www.dicks- blog.com/archives/2004/06/03/external-data-mixed-data-types/

Usando essa seqüência de conexão:

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

com Excel 2010 Tenho notado o seguinte. Se o arquivo de Excel é aberto quando você executar o OLEDB SELECIONAR então você obtém a versão atual das células, não os valores de arquivo salvo. Além disso os valores de cadeia voltou para uma série longa, o valor decimal e data parecido com este:

5.0130370071e+012
4.08
36808

Se o arquivo não está aberto, em seguida, os valores devolvidos são:

5013037007084
£4.08
Monday, October 09, 2000

Se você olhar para o arquivo .xslx real usando o Open XML SDK 2.0 Produtividade Tool (ou simplesmente Descompacte o arquivo e ver o XML no bloco de notas), você vai ver que Excel 2007, na verdade, armazena os dados brutos no formato científico.

Por exemplo 0,00001 é armazenado 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>

Olhando para a célula no Excel sua exibido como 0,00001, tanto no celular e barra de fórmulas. Por isso nem sempre é verdade que OleDB está causando o problema.

Eu descobri que a maneira mais fácil é para escolher o formato Zip, em vez de formato de texto para colunas com grandes 'números'.

Você já tentou converter o valor do campo para (int) ou talvez (Int64), como você está lendo isso?

Procure a opção de string = 1 conexão IMEX e TypeGuessRows Configuração do Registro no google. Na verdade, não há nenhuma maneira fácil contornar isso porque os tipos de dados infere leitor da coluna, olhando para as primeiras filas (8 por padrão). Se as linhas contêm todos os números, então você está fora de sorte.

Uma solução infeliz que eu usei no passado é usar a opção seqüência de conexão HDR = NO e definir as TypeGuessRows Registro definir o valor para 1, o que obriga a ler a primeira linha como dados válidos para fazer a sua determinação tipo de dados , mais do que um cabeçalho. É um hack, mas funciona. O código lê a primeira linha (contendo o cabeçalho) como texto, e em seguida, define o tipo de dados em conformidade.

A alteração do registro é uma dor (e nem sempre possível) mas eu recomendo restaurar o valor original depois.

Se os dados de importação não tem uma linha de cabeçalho, em seguida, uma opção alternativa é a pré-processar o arquivo e inserir um 'personagem antes cada um dos números na coluna ofensivo. Isso faz com que os dados da coluna a ser tratado como texto.

Portanto, tudo somado, há um monte de hacks para contornar este, mas nada realmente infalível.

Eu tive esse mesmo problema, mas foi capaz de trabalhar em torno dele sem recorrer à interface Excel COM ou software 3rd party. Trata-se de um pouco de processamento de sobrecarga, mas parece estar a trabalhar para mim.

  1. Primeiro ler os dados para obter os nomes das colunas
  2. Em seguida, crie um novo DataSet com cada uma dessas colunas, definindo cada um dos seus tipos de dados de string.
  3. Leia os dados novamente para este novo dataset. Voila - o científica notação é ido agora e tudo é lido como uma string.

Aqui está um código que ilustra isso, e como um bônus adicional, é ainda 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.
                        }
                    }
                }
            }
        }
    }
}

Eu pesquisei em torno deste estado .. Aqui estão os meus passos solulition

  • Para arquivo excel template

1-formato coloumn Excel como texto 2 escrita macro para desativar os avisos de erro para Number -> texto conversão

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

3 durante a leitura de dados para importação tentar analisar dados de entrada para Int64 ou Int32 ....

Estou interessado em saber se alguém tem uma resposta para isso. Eu estive acima e abaixo os interwebs e tentei todas as combinações de IMEX e HDR. IMEX = 1 é o único que eu consegui data extrato, moeda e valores gerais Número com. Mas grandes números ainda mostram como científico. Eu só preciso ler arquivos e mudanças de planilhas, registro, 3rd party não é uma opção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top