Como posso impedir que o Excel coma meus deliciosos arquivos CSV e excrete dados inúteis?

128

Eu tenho um banco de dados que rastreia as vendas de widgets por número de série. Os usuários inserem dados e quantidade do comprador e digitalizam cada widget em um programa cliente personalizado. Eles finalizam o pedido. Tudo isso funciona perfeitamente.

Alguns clientes desejam uma planilha compatível com o Excel dos widgets que adquiriram. Geramos isso com um script PHP que consulta o banco de dados e gera o resultado como um CSV com o nome da loja e os dados associados. Isso funciona perfeitamente bem também.

Quando aberto em um editor de texto como o Bloco de Notas ou vi, o arquivo fica assim:

"Account Number","Store Name","S1","S2","S3","Widget Type","Date"
"4173","SpeedyCorp","268435459705526269","","268435459705526269","848 Model Widget","2011-01-17"

Como você pode ver, os números de série estão presentes (neste caso duas vezes, nem todos os seriais secundários são iguais) e são longas seqüências de números. Quando esse arquivo é aberto no Excel, o resultado se torna:

Account Number  Store Name  S1  S2  S3  Widget Type Date 
4173    SpeedyCorp  2.68435E+17     2.68435E+17 848 Model Widget    2011-01-17

Como você deve ter observado, os números de série são colocados entre aspas duplas. O Excel parece não respeitar qualificadores de texto em arquivos .csv. Ao importar esses arquivos para o Access, temos zero dificuldades. Ao abri-los como texto, sem problemas. Mas o Excel, sem falhas, converte esses arquivos em lixo inútil. Tentar instruir os usuários finais na arte de abrir um arquivo CSV com um aplicativo não padrão está se tornando, digamos, cansativo. Existe esperança? Existe uma configuração que não consegui encontrar? Esse parece ser o caso do Excel 2003, 2007 e 2010.

atroon
fonte
46
posso dar um +1 apenas pelo nome?
precisa saber é o seguinte
11
Excel does not seem to respect text qualifiers in .csv files- as aspas duplas não são qualificadores de texto, elas simplesmente permitem vírgulas nos seus dados; se você não usar vírgulas nos dados, elas não terão sentido . Todos os dados em um arquivo CSV não são digitados, portanto, o Excel pode apenas adivinhar que seu número de série grande é um número , e é aí que você encontra a precisão máxima do Excel de 15 dígitos, que é o que está truncando seus números.
DMA57361
1
O Excel parece não respeitar todas as vírgulas entre aspas duplas. Considere "12 de agosto de 2012" O Excel também transforma isso em lixo.
Zundarz
5
Eu quero mencionar esta pergunta SU . Explica quais opções você tem ao lidar com CSV no Excel.
Nixda
1
@nixda Thanks! Essas são sugestões úteis, especialmente para usuários mais experientes. Meu problema é quase um problema humano, pois o Excel se associa a arquivos .csv, as pessoas veem o ícone e clicam duas vezes (porque é assim que você abre as coisas) e, em seguida, geralmente clicam em Salvar (porque estamos sempre dizendo salvá-los!), e tudo está perdido. Mas definitivamente vou usar seus métodos quando possível.
Atroon

Respostas:

58

Mas o Excel, sem falhas, converte esses arquivos em lixo inútil.

Excel é lixo inútil.

Solução

Eu ficaria um pouco surpreso se algum cliente que desejasse seus dados em um formato Excel não conseguisse alterar a formatação visível nessas três colunas para "Número" com zero casas decimais ou "texto". Mas vamos supor que um pequeno documento de instruções esteja fora de questão.

Suas opções são:

  1. Ative um caractere não numérico e não em espaço em branco nos números de série.
  2. Escreva um arquivo xls ou xlsx com alguma formatação padrão.
  3. Trapaça e produza esses números como fórmulas ="268435459705526269","",="268435459705526269"(você também pode ="268435459705526269",,="268435459705526269"salvar 2 caracteres). Isso tem a vantagem de ser exibido corretamente, e provavelmente sendo geralmente útil, mas sutilmente quebrado (como são fórmulas).

Tenha cuidado com a opção 3, porque alguns programas (incluindo Excel e Open Office Calc) não tratam mais vírgulas dentro de =""campos como escapadas. Isso significa ="abc,xyz"que abrange duas colunas e interromperá a importação.

O uso do formato de "=""abc,xy"""resolve esse problema, mas esse método ainda o limita a 255 caracteres devido ao limite de comprimento da fórmula do Excel.

Tyler
fonte
1
Na verdade, isso não está sendo duro. Copie e cole um dos números acima no Excel e altere o formato do número, conforme sugerido. O Excel altera o valor, resultando em lixo.
Joe Internet
1
@ Joe, eu era muito superficial na minha visão geral inicial. O Excel está realmente produzindo lixo e é ele próprio lixo. Atualizei minha resposta para refletir isso. Uma opção pode estar tendo um "CSV Excel" e também ter uma "utilizável, csv pena"
Tyler
2
@ Tyler - Eu não acho que o Excel seja lixo, apenas dizendo que o OP estava correto ao produzir lixo nesse caso. Na verdade, é uma pergunta muito boa, sem solução aparentemente elegante.
Joe Internet
1
A opção Formatar células ... foi sugerida e tentei usá-la. Nesse caso, no momento em que você abre o arquivo, o Excel parece converter as séries em notação científica (acordada, não inesperada) e lança a precisão. Quando você os altera para um número ou texto, a sequência não volta. Essa é realmente a essência do problema. Produzir como fórmulas pode fazê-lo ... Não pensei nisso.
Atroon
9
@ DMA57361 O comportamento não é esperado, é determinável. A precisão numérica está bem documentada, como o Excel lê CSVs não. A falta de aviso e o descarte silencioso de dados é absurda. O fato de você não poder nem dizer ao Excel como importar os dados é igualmente absurdo. A negatividade é necessária ? Não, mas a honestidade é a melhor política e é assim que me sinto.
Tyler
42

Tivemos um problema semelhante no qual tínhamos arquivos CSV com colunas contendo intervalos como 3-5 e o Excel sempre os convertia para datas, por exemplo, 3-5 seria 3 de março, após o que a mudança para numérico nos deu um número inteiro inútil da data. Nós contornamos isso

  1. Renomeando a extensão CSV para TXT
  2. Então, quando o abrimos no Excel, isso ativaria o assistente de importação de texto
  3. Na Etapa 3 de 3 do assistente , informamos que as colunas em questão eram texto e foram importadas corretamente.

Você poderia fazer o mesmo aqui, eu acho.

assistente de importação de texto

Felicidades

user65525
fonte
2
+1 por ser a maneira correta de fazer isso. (edit: sorry teve que editar um pouco para esclarecer solução)
jay
2
Você não precisa renomear seu arquivo. Basta usar o assistente de importação. Shift-selecione todas as colunas e escolha como texto.
Nixda
1
Assistente de importação de texto é a resposta. Todas as outras soluções são invasões desnecessárias, resultantes do não entendimento de como usar o Excel para exibir e editar CSVs.
Excellll
1
@ Excel, fazendo um arquivo de cada vez, com certeza. Ao automatizar esse processo, o 'hackery desnecessário' geralmente salva o dia.
Parrish Marido
1
isso é completamente inútil quando o Excel é usado por usuários padrão para exibir arquivos CSV. Antes de tentar explicar como usar o assistente de importação de texto para ~ 15 usuários de escritório iniciante, prefiro digitar o código fonte do documento do Excel sozinho.
Northkildonan
8

Melhor solução é gerar XML Workbook. Como isso:

<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  </OfficeDocumentSettings>

  <ss:Worksheet ss:Name="Sheet 1">
    <Table>
    <Column ss:Width="100"/>
    <Column ss:Width="100"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="80"/>
    <Column/>

    <Row>
      <Cell><Data ss:Type="String">Account Number</Data></Cell>
      <Cell><Data ss:Type="String">Store Name</Data></Cell>
      <Cell><Data ss:Type="String">S1</Data></Cell>
      <Cell><Data ss:Type="String">S2</Data></Cell>
      <Cell><Data ss:Type="String">S3</Data></Cell>
      <Cell><Data ss:Type="String">Widget Type</Data></Cell>
      <Cell><Data ss:Type="String">Date</Data></Cell>
    </Row>

    <Row>
      <Cell><Data ss:Type="String">4173</Data></Cell>
      <Cell><Data ss:Type="String">SpeedyCorp</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">x</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">848 Model Widget</Data></Cell>
      <Cell><Data ss:Type="String">2011-01-17</Data></Cell>
    </Row>


    </Table>
    <x:WorksheetOptions/>
  </ss:Worksheet>
</Workbook>

O arquivo deve ter extensão .xml. Excel e OpenOffice abrem-no corretamente.

twentybeersreserved
fonte
Você quer dizer que o OP deve usar o script PHP para converter o banco de dados em formato XML?
Prasanna
2
Muito mais limpo do que fazer com que os usuários abram .csv no Excel ou atrapalhem seu CSV, para que apenas o Excel possa entender seu CSV. Nem sequer é um esquema tão complexo.
binki
Onde esse padrão está documentado? Gostaria de saber mais sobre os tipos de dados disponíveis.
John Doherty
1

Minha solução: tenho o mesmo problema com a importação de números de série. Eles não precisam ser tratados como números, ou seja, nenhuma função matemática é executada nele, mas precisamos do número inteiro lá. A coisa mais simples que tenho é inserir um espaço no número de série. por exemplo, "12345678 90123456 1234". Quando o Excel o importa, ele será tratado como texto em vez de numérico.

Peterlip
fonte
0

Eu tinha números de conta longos sendo ilegíveis.

Foi assim que eu consertei:

Abra seu arquivo.csv no Libre Office / Open Office (pode ser necessário especificar delimitadores, etc.) e salve o arquivo como um arquivo XML do Excel.

Em seguida, abra esse arquivo no Excel e você verá que as colunas não serão mais alteradas para o formato científico ou o que for. Para segurança, clique com o botão direito do mouse na coluna e defina explicitamente o formato como Texto e salve como formato de arquivo do Excel.

Abra o arquivo no formato Excel e a coluna ainda deve estar ok!

user127379
fonte
1
Enquanto isso iria trabalhar, tentando explicar a alguém que só fala Inglês quebrado por que ele precisaria usar uma suíte de escritório diferente cria tantos problemas quanto os resolve. Software alternativo para o M $ Office é bom em minha opinião, mas percebo que não posso converter todos.
Atroon
0

O Assistente de Importação é a melhor solução para usuários casuais e situações pontuais. Se você precisar de uma solução programática, poderá usar o método QueryTables.Add (que é o que o Assistente de Importação está usando nos bastidores).

Workbooks.Add
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & "C:\myfile.csv", Destination:=Range("$A$1"))
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 437
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = False
    .TextFileCommaDelimiter = True
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(1, 2, 2) 'Edit this line. Add a number for each column, 1 is general, 2 is text. Search the internet for other formats.
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
End With
PBeezy
fonte