Как я могу помешать Excel съесть мои восхитительные CSV-файлы и извлечь ненужные данные?

128

У меня есть база данных, которая отслеживает продажи виджетов по серийному номеру. Пользователи вводят данные и количество покупателя и сканируют каждый виджет в пользовательскую клиентскую программу. Затем они завершают заказ. Это все работает без нареканий.

Некоторым клиентам нужна совместимая с Excel электронная таблица приобретенных ими виджетов. Мы генерируем это с помощью PHP-скрипта, который запрашивает базу данных и выводит результат в виде CSV с именем магазина и связанными данными. Это тоже прекрасно работает.

При открытии в текстовом редакторе, таком как Блокнот или vi, файл выглядит следующим образом:

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

Как видите, серийные номера присутствуют (в этом случае дважды, не все вторичные серийные номера одинаковы) и представляют собой длинные строки чисел. Когда этот файл открывается в Excel, результат становится:

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

Как вы могли заметить, серийные номера заключены в двойные кавычки. Excel, похоже, не учитывает квалификаторы текста в файлах .csv. При импорте этих файлов в Access у нас нет никаких трудностей. При открытии их как текста, никаких проблем вообще нет. Но Excel, в обязательном порядке, превращает эти файлы в бесполезный мусор. Попытка проинструктировать конечных пользователей об открытии файла CSV с помощью приложения не по умолчанию становится, скажем так, утомительной. Есть ли надежда? Есть ли настройка, которую я не смог найти? Это похоже на случай с Excel 2003, 2007 и 2010.

atroon
источник
46
Могу ли я дать +1 только за имя?
tombull89
11
Excel does not seem to respect text qualifiers in .csv files- двойные кавычки не являются текстовыми квалификаторами, они просто допускают запятые в ваших данных, если вы не используете запятые в своих данных, то они не имеют смысла . Все данные в CSV-файле нетипизированы, поэтому в Excel можно только догадываться, что ваш большой серийный номер - это число , и именно тогда вы наберете максимальную точность Excel, равную 15 цифрам, что и является усечением ваших чисел.
DMA57361
1
Excel, похоже, не учитывает все запятые в двойных кавычках. Рассмотрим «12 августа 2012 года». Excel также превращает это в мусор.
zundarz
5
Я хочу упомянуть этот вопрос SU . Он объясняет, какие варианты у вас есть при работе с CSV в Excel.
nixda
1
@ nixda Спасибо! Это полезные предложения, особенно для более опытных пользователей. Моя проблема - почти человеческая проблема, в которой Excel связывается с файлами .csv, и люди видят значок, и дважды щелкают (потому что именно так вы открываете вещи), а затем обычно нажимаете Сохранить (потому что мы всегда говорим их сохранить!) и все потеряно. Но я обязательно буду использовать ваши методы, когда это возможно.
августа

Ответы:

58

Но Excel, в обязательном порядке, превращает эти файлы в бесполезный мусор.

Excel это бесполезный мусор.

Решение

Я был бы немного удивлен, если бы любой клиент, желающий получить ваши данные в формате Excel, не смог изменить видимое форматирование в этих трех столбцах на «Число» с нулевыми десятичными разрядами или на «текст». Но давайте предположим, что короткий документ с практическими рекомендациями исключен.

Ваши варианты:

  1. Бросьте не числовые, а не пробельные символы в ваши серийные номера.
  2. Запишите файл xls или файл xlsx с некоторым форматированием по умолчанию.
  3. Обманывайте и выводите эти числа в виде формул ="268435459705526269","",="268435459705526269"(вы также можете ="268435459705526269",,="268435459705526269"сэкономить 2 символа). Это имеет преимущество в правильном отображении и, вероятно, в целом полезном, но едва различимом (поскольку они являются формулами).

Будьте осторожны с вариантом 3, потому что некоторые программы (включая Excel и Open Office Calc) больше не будут обрабатывать запятые внутри =""полей как экранированные. Это означает, что ="abc,xyz"будет охватывать два столбца и прервать импорт.

Использование формата "=""abc,xy"""решает эту проблему, но этот метод все еще ограничивает вас 255 символами из-за ограничения длины формулы Excel.

Тайлер
источник
1
На самом деле, это не так резко. Скопируйте и вставьте одно из указанных выше чисел в Excel, затем измените формат чисел в соответствии с предложением. Excel изменяет значение, что приводит к мусору.
Джо Интернет
1
@ Джо, я был слишком поверхностен в своем первоначальном обзоре. Excel действительно производит мусор и сам является мусором. Я обновил свой ответ, чтобы отразить это. Опция может иметь «Excel CSV», а также «пригодный для использования CSV»
Тайлер
2
@Tyler - я не думаю, что Excel - это мусор, я просто говорю, что OP правильно, что в этом случае он производит мусор. На самом деле это очень хороший вопрос, без элегантного решения.
Джо Интернет
1
Была предложена опция Формат ячеек ..., и я попытался ее использовать. В этом случае, как только вы открываете файл, Excel, кажется, преобразует сериалы в научную нотацию (согласованную, а не неожиданную) и отбрасывает точность. Когда вы меняете их на число или текст, строка не возвращается. Это действительно суть проблемы. Вывод в виде формул может сделать это, хотя ... Я не думал об этом.
atroon
9
@ DMA57361 Поведение не ожидается, его можно определить. Числовая точность хорошо задокументирована, как Excel читает CSV - нет. Отсутствие предупреждения и молчаливого сброса данных абсурдно. Тот факт, что вы даже не можете сказать Excel, как импортировать данные, также абсурден. Нужен ли негатив ? Нет, но честность - лучшая политика, и я так себя чувствую.
Тайлер
42

У нас была похожая проблема, когда у нас были CSV-файлы со столбцами, содержащими диапазоны, такие как 3-5, и Excel всегда конвертировал бы их в даты, например 3-5 было бы 3 марта, после чего переключение на числовые значения давало нам бесполезное целое число даты. Мы обошли это

  1. Переименование расширения CSV в TXT
  2. Затем, когда мы открыли его в Excel, это включило бы мастер импорта текста
  3. На шаге 3 из 3 в мастере мы сказали, что рассматриваемые столбцы были текстовыми, и они были импортированы правильно.

Вы могли бы сделать то же самое здесь, я думаю.

Мастер импорта текста

ура

user65525
источник
2
+1 за правильный способ сделать это. (редактирование: жаль было изменить немного уточнить решение)
JAY
2
Вам не нужно переименовывать свой файл. Просто используйте мастер импорта Shift-выделите все столбцы и выберите текст.
nixda
1
Мастер импорта текста - это ответ. Все остальные решения являются ненужным взломом, возникающим из-за непонимания того, как использовать Excel для просмотра и редактирования CSV.
Excellll
1
@Excellll, делая это по одному файлу за раз. При автоматизации этого процесса «ненужное хакерство» часто спасает день.
Парриш Муж
1
это совершенно бесполезно, когда обычные пользователи используют Excel для отображения файлов CSV. прежде чем я попытаюсь объяснить, как использовать text-import-wizard для ~ 15 начинающих офисных пользователей, я бы лучше сам набрал исходный код документа Excel.
Норткилдонан
8

Лучшим решением является создание XML Workbook. Нравится:

<?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>

Файл должен иметь расширение .xml. Excel и OpenOffice открывают его правильно.

twentybeersreserved
источник
Вы имеете в виду, что ОП должен использовать PHP-скрипт для преобразования базы данных в формат XML?
Прасанна
2
Это намного чище, чем когда пользователи открывают .csv в Excel или портят ваш CSV, так что только Excel может понять ваш CSV. Это даже не тот комплекс схемы.
Бинки
Где этот стандарт задокументирован? Я хотел бы узнать больше о доступных типах данных.
Джон Доэрти
1

Мое решение: у меня та же проблема с импортом серийных номеров. Они не должны рассматриваться как числа, то есть никакие математические функции не выполняются, но нам нужно полное число там. Самое простое, что у меня есть, это вставить пробел в серийный номер. например, «12345678 90123456 1234». Когда Excel импортирует его, он будет обрабатываться как текст, а не как цифра.

Peterlip
источник
0

У меня были искажены длинные номера счетов.

Вот как я это исправил:

Откройте файл file.csv в Libre Office / Open Office (может потребоваться указать разделители и т. Д.), Затем сохраните файл как файл Excel XML.

Затем откройте этот файл в Excel, и вы увидите, что столбцы больше не преобразуются в научный формат или что-то еще. Для безопасности щелкните правой кнопкой мыши по столбцу и явно задайте формат как Текст, затем сохраните как формат файла Excel.

Откройте файл формата Excel, и колонка должна быть в порядке!

user127379
источник
1
В то время как это будет работать, пытаясь объяснить кому - то , кто говорит только на ломаном английском , почему он должен был бы использовать другой офисный пакет создает столько же проблем , как это решает. По моему мнению, альтернатива M $ Office хороша, но я понимаю, что не могу всех преобразовать.
августа
0

Мастер импорта - лучшее решение для случайных пользователей и разовых ситуаций. Если вам нужно программное решение, вы можете использовать метод QueryTables.Add (который используется мастером импорта за кулисами).

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
источник