Ошибка при импорте csv файла

sergey-nv

2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

1

16.09.2020, 08:35. Показов 2967. Ответов 20

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Есть база данных mysql. В ней таблица po. В таблице 98 записей, в поле id_po последнее значение 100. Я делаю импорт в таблицу из файла csv.

Файл csv вот:

HTML5
1
2
3
4
5
101;"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
102;"Виртуальная лабораторная работа ""Закалка углеродистой стали""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
103;"Виртуальная лабораторная работа ""Микроскопический анализ металлов""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
104;"Виртуальная лабораторная работа ""Структура сварных соединений";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
105;"Виртуальная лабораторная работа ""Твердость зон сварного шва""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

и так далее.

При импорте появляется сообщение об ошибке:

INSERT INTO `po` VALUES (‘1’, ‘3D Атлас «Редукторы».’, ‘Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года’, », ‘0’)

#1062 — Duplicate entry ‘1’ for key ‘PRIMARY’

Почему он пытается импортировать данные, начиная с id_po = 1, когда в csv id_po начинается с 101? Как сделать импорт?



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

16.09.2020, 08:35

20

537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 10:03

2

сам запрос с лоад локал инфайл можно посмотреть?



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 10:11

 [ТС]

3

DimaxDe, не понял о чем вы говорите. Я в phpmyadmin нажимаю импорт, выбираю файл csv, разделителем выбираю — ; и жму вперед, появляется ошибка, импорта не происходит.



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 10:14

4

как я понял у вас айди не автоинкремент?



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 10:15

 [ТС]

5

DimaxDe, да, пробовал проставлять — все равно не импортирует.



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 10:17

6

если айди автоинкремент то его вообще ненадо указывать.



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 10:24

 [ТС]

7

DimaxDe, то есть поставить для id автоинкремент, в csv id оставить пустыми и импортировать? А он проставит id автоматом, начиная с 101? Или сначала вставит туда, где есть дыры (у меня, к примеру, нет id = 79 и 80, после 78 сразу идет 81)?



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 10:36

8

помоему он начинает с мах+1..дыры не заполнит

Добавлено через 10 минут
все понятно..у вас айди в таблице стоит тип варчар и когда вы вставляете 101 он принимает 0 как конец слова



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 10:55

 [ТС]

9

DimaxDe, нет, для id стоит тип int



0



DimaxDe

537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 11:15

10

попробуйте такой запрос:

SQL
1
2
ALTER TABLE ваша_таблица 
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ;

а потом импорт без айдишников.

Добавлено через 2 минуты
из ошибки видно ,что при импорте число с айди преобразуется в строковое значение..



0



sergey-nv

2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 12:06

 [ТС]

11

Делаю импорт без id. Файл csv вот:

HTML5
1
2
3
4
5
;"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;"Виртуальная лабораторная работа ""Закалка углеродистой стали""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;"Виртуальная лабораторная работа ""Микроскопический анализ металлов""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;"Виртуальная лабораторная работа ""Структура сварных соединений";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;"Виртуальная лабораторная работа ""Твердость зон сварного шва""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

Пишет: «Несоответствие количества столбцов в CSV данных на строке 1»

и так пробовал:

HTML5
1
2
3
4
5
;;"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;;"Виртуальная лабораторная работа ""Закалка углеродистой стали""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;;"Виртуальная лабораторная работа ""Микроскопический анализ металлов""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;;"Виртуальная лабораторная работа ""Структура сварных соединений";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
;;"Виртуальная лабораторная работа ""Твердость зон сварного шва""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

и так:

HTML5
1
2
3
4
5
 ;"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
 ;"Виртуальная лабораторная работа ""Закалка углеродистой стали""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
 ;"Виртуальная лабораторная работа ""Микроскопический анализ металлов""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
 ;"Виртуальная лабораторная работа ""Структура сварных соединений";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
 ;"Виртуальная лабораторная работа ""Твердость зон сварного шва""";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

Та же ошибка — «Несоответствие количества столбцов в CSV данных на строке 1»
Как сделать импорт?



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 12:18

12

Цитата
Сообщение от sergey-nv
Посмотреть сообщение

;

эти все первые убрать..

Добавлено через 4 минуты
точка с запятой у вас является делителем,делит столбцы друг от друга тоесть ваша строка начинаясь так :
;»3D Атлас «»Редукторы»».» преобразуется в 2 значения нулл и «3D Атлас «»Редукторы»».»



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 12:19

 [ТС]

13

DimaxDe, убирал — та же ошибка — «Несоответствие количества столбцов в CSV данных на строке 1»



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 12:21

14

а такая строка ;;»3D Атлас «»Редукторы»».» — в нулл нулл «3D Атлас «»Редукторы»».»

Добавлено через 1 минуту
сколько столбцов у вас в таблице вместе с ид?



0



2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 12:26

 [ТС]

15

DimaxDe, да, но первый столбец — это id c автоинкрементом. То есть должен вставляться не null, а значение id = max+1

Добавлено через 1 минуту
DimaxDe, пять столбцов вместе с id

Добавлено через 3 минуты
DimaxDe, а может быть, дело в изменении настроек хостинга? Я почитал про ошибку «#1062 — Duplicate entry ‘1’ for key ‘PRIMARY'», пишут, что возникает при переходе на другой хостинг.



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 12:28

16

Цитата
Сообщение от sergey-nv
Посмотреть сообщение

;»3D Атлас «»Редукторы»».»;Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

каждая строка должна быть типа:
«3D Атлас «»Редукторы»».»;Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0
здесь 4 значения и 5 это айди..никаких ошибок не должно быть

Добавлено через 1 минуту
сейчас же нет такой ошибки?



0



sergey-nv

2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 12:33

 [ТС]

17

DimaxDe, есть, при том что я только одну строчку сделал в csv:

HTML5
1
"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0



0



sergey-nv

2 / 2 / 0

Регистрация: 15.04.2019

Сообщений: 202

16.09.2020, 12:41

 [ТС]

19

DimaxDe, понял, код изначально был правильным:

HTML5
1
;"3D Атлас ""Редукторы"".";Договор купли-продажи №53/03-20Е-44 от 09 сентября 2020 года;;0

только нужно было кодировку файла поставить без BOM

с BOM — это же один невидимый символ в самом начале файла



0



537 / 349 / 193

Регистрация: 07.11.2018

Сообщений: 1,213

16.09.2020, 12:47

20

да возможно и транкет помог бы..но я не пользуюсь админом..всё по старинке ) сам пишу..ну слав богу разобрались.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

16.09.2020, 12:47

20

Проблемы

При попытке импорта файла значений с разделителями запятыми (CSV) в Outlook 2010 или Outlook 2013 ри, появится следующее сообщение об ошибке:

Перевод ErrorA файл ошибка в трансляторе значения, разделенные запятыми при инициализации транслятора для создания таблицы соответствия полей. Outlook не удалось извлечь данные из файла < имя файла >. Убедитесь, что у вас есть правильный файл, наличие разрешения на ее открытие, и что он не открыт в другой программе.

Причина

CSV-файл, который вы хотите импортировать не использует управляющие символы CR + LF (возврат каретки + перевод строки) для представления разрывов.

Решение

Откройте CSV-файл в другом приложении, например Microsoft Excel, а затем используйте «Сохранить как» для сохранения содержимого в формате CSV. Затем используйте Outlook для импорта нового CSV-файла.

Дополнительная информация

Строка разделителя записи называются знаки, которые используются для представления разрыва строки. В некоторых системах Mac или Unix может представлять разрыв строки, используя только управляющий символ перевода строки (LF). Другие системы могут использовать управляющие символы разрыва совершенно другой строки.

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.

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

Проф-Диалог

Новый, полностью переработанный курс А. М. Князева «Диагностика личностно-профессиональных компетенций». Первые два занятия бесплатно!

Иероглифы при открытии .csv файла с помощью Excel: решение проблемы

При выгрузке .csv таблицы в Excel у многих пользователей неверно отображаются данные. Вместо кириллических символов в документе вы можете увидеть иероглифы. Выглядит это примерно так:

Проблема возникает потому, что кодировка csv файла отличается от той, которая используется MS Excel по умолчанию. В этой статье мы рассмотрим два варианта быстрого решения этой проблемы.

Вариант №1. В самом Excel

Шаг 1. Откройте MS Excel.

Шаг 2. Перейдите во вкладку «Данные».

Шаг 3. Нажмите «Получить данные», затем из файла, затем «Из текстового/CSV файла».

Шаг 4. В открывшемся окне в правом нижнем углу выберите опцию «Все файлы».

Шаг 5. Найдите в этом окне .csv файл, который нужно исправить. Нажмите «Импорт».

Шаг 6. В открывшемся окне нажмите «Загрузить».

Шаг 7. Готово! Создан новый лист, и данные в нем отображаются корректно.

Вариант №2. С помощью Google Таблиц (Google Sheets)

Шаг 1. Убедитесь, что вы авторизованы в своем аккаунте Google.

Шаг 3. В разделе «Создать таблицу» нажмите «Пустой файл».

Шаг 4. Откроется страница с пустой таблицей. Нажмите «Файл», затем «Импортировать».

Шаг 5. В открывшемся окне нажмите «Загрузка», затем «Выбрать файл на устройстве».

Шаг 6. Найдите в новом окне .csv файл, который нужно исправить. Нажмите «Открыть».

Шаг 7. Нажмите «Импортировать данные».

Шаг 8. Готово! Таблица импортирована, данные изображаются корректно.

Вы можете дальше работать с файлом прямо в Google Таблицах, либо экспортировать файл, чтобы работать с ним в другой программе (например, MS Excel).
Чтобы экспортировать файл, нажмите «Файл», затем «Скачать», затем выберите нужный формат (например Microsoft Excel).

Импорт файла CSV может быть неприятным. Мы все боролись с импортом и повторным импортом файла, который все еще содержит надоедливые, трудно идентифицируемые проблемы. Хотя ошибки импорта CSV могут сильно различаться, мы заметили, что люди, вероятно, будут сталкиваться с одной и той же горсткой ошибок синтаксического анализа CSV снова и снова. Если вы научитесь выявлять и устранять эти ошибки, импорт данных может занять значительно меньше времени и энергии… чего мы все хотели бы иметь больше.

Мы здесь, чтобы помочь, используя как пять советов ниже, так и наш удаленный браузер для файлов CSV в облаке. CSV Studio предлагает надежный синтаксический анализатор и автоматическое исправление ошибок для несовместимых и плохо отформатированных файлов CSV. Он позволяет удаленно просматривать файлы на сервере данных, автоматически выявлять и исправлять ошибки и экспортировать файл в базу данных без ошибок синтаксического анализа. Смотрите демонстрации, чтобы узнать больше.

# 1 — Нераспознанный Юникод / ​​недопустимая кодовая точка

Даже если это не самая распространенная проблема, это определенно первая проблема, с которой вы можете столкнуться при работе с CSV. Если вы используете python для обработки данных, эта проблема проявится очень быстро, поскольку ввод-вывод python вызовет исключение при первых признаках проблемы. Многие парсеры не могут отображать или обрабатывать текстовое поле с недопустимым кодом, и вы вынуждены немедленно найти правильную кодировку, прежде чем пытаться выполнить любую дальнейшую диагностику.

Утилита, такая как команда «file -e», может работать, если для работы достаточно кодовых точек. Имейте в виду, что даже несмотря на то, что большая часть Интернета и персональных компьютеров принимает кодировку UTF-8 по умолчанию как должное, ISO-8859 Latin-1 так же хорош, как и любой другой, для данных, происходящих из базы данных.

# 2 — Текстовое поле с неэкранированным разделителем

Если разделитель столбцов отображается в текстовом поле без экранирования, это приведет к тому, что в строке появится дополнительный столбец. Обычно проблема возникает, когда в CSV-файле не используются двойные кавычки для заключения текстовых и числовых полей. Имена и адреса часто являются результатом ввода с клавиатуры, что означает, что они могут содержать все виды управляющих символов: /, , |, ^, стрелки влево и вправо, возврат каретки, перевод строки и т. Д.

Рациональное решение — повторно экспортировать файл, заключив столбцы в двойные кавычки. Если это невозможно и возникает необходимость удалить лишние разделители, использование CSV Studio для исключения лишних разделителей может помочь вам сохранить рассудок.

# 3 — Строка в кавычках с неэкранированными двойными кавычками

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

Случайное использование DJ ”S вместо DJ’S создает единственную проблему в файле с 600 000 строками. Эта проблема является фатальной: остальная часть файла отображается как одна строка. Наилучший подход — повторно экспортировать файл CSV и правильно избегать двойных кавычек. Если это необходимо сделать после того, как это произошло, в CSV Studio есть алгоритм для поиска лишних двойных кавычек, которые нужно экранировать.

# 4 — Нестандартные escape-символы

Файлы в стиле Unix часто используют обратную косую черту () внутри строк в кавычках, чтобы избежать разделителя строк.

›« В этой строке есть »

Однако вместо использования обратной косой черты CSV-файлы RFC-4180 удваивают разделитель строк в качестве механизма выхода.

›« В этой строке есть «» »

При кодировании файлов CSV следует последовательно применять один из этих механизмов выхода. Однако иногда встречаются файлы, в которых одновременно используются оба метода выхода. Это создает двусмысленность всякий раз, когда встречается escape-последовательность (см. Таблицу).

# 5 — Окончания строк CRLF / Dos

Концы строк не являются проблемой для CSV. Окончания строк в Windows и Unix различаются, и это, конечно, повлияет на файлы данных так же, как и на любой другой файл. Официальный разделитель строк RFC 4180 для CSV — это последовательность CRLF (символ возврата каретки, за которым следует символ новой строки). При обработке файла CSV с окончанием строки CRLF нередко обнаруживается нежелательный символ ^ M (или CR) в конце каждой строки. Это может даже вызвать проблемы с некоторыми парсерами CSV. Обработка файла с помощью утилиты dos2unix — стандартный способ решения этой проблемы.

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

Время на прочтение
11 мин

Количество просмотров 368K

CSV является стандартом де-факто для связи между собой разнородных систем, для передачи и обработки объемных данных с «жесткой», табличной структурой. Во многих скриптовых языках программирования есть встроенные средства разбора и генерации, он хорошо понятен как программистам, так и рядовым пользователям, а проблемы с самими данными в нем хорошо обнаруживаются, как говорится, на глаз.

История этого формата насчитывает не менее 30 лет. Но даже сейчас, в эпоху повального использования XML, для выгрузки и загрузки больших объемов данных по-прежнему используют CSV. И, несмотря на то, что сам формат довольно неплохо описан в RFC, каждый его понимает по-своему.

В этой статье я попробую обобщить существующие знания об этом формате, указать на типичные ошибки, а также проиллюстрировать описанные проблемы на примере кривой реализации импорта-экспорта в Microsoft Office 2007. Также покажу, как обходить эти проблемы (в т.ч. автоматическое преобразование типов Excel-ом в DATETIME и NUMBER) при открытии .csv.

Начнем с того, что форматом CSV на самом деле называют три разных текстовых формата, отличающихся символами-разделителями: собственно сам CSV (comma-separated values — значения, разделенные запятыми), TSV (tab-separated values — значения, разделенные табуляциями) и SCSV (semicolon separated values — значения, разделенные точкой с запятой). В жизни все три могут называться одним CSV, символ-разделитель в лучшем случае выбирается при экспорте или импорте, а чаще его просто «зашивают» внутрь кода. Это создает массу проблем в попытке разобраться.

Как иллюстрацию возьмем казалось бы тривиальную задачу: импортировать в Microsoft Outlook данные из таблицы в Microsoft Excel.

В Microsoft Excel есть средства экспорта в CSV, а в Microsoft Outlook — соответствующие средства импорта. Что могло быть проще — сделал файлик, «скормил» почтовой программе и — дело сделано? Как бы не так.

Создадим в Excel тестовую табличку:

Текстовая табличка

… и попробуем экспортировать ее в три текстовых формата:

«Текст Unicode» Кодировка — UTF-16, разделители — табуляция, переводы строк — 0×0D, 0×0A, объем файла — 222 байт
«CSV (разделители — запятые)» Кодировка — Windows-1251, разделители — точка с запятой (не запятая!), во второй строке значение телефонов не взято в кавычки, несмотря на запятую, зато взято в кавычки значение «01;02», что правильно. Переводы строк — 0×0D, 0×0A. Объем файла — 110 байт
«Текстовые файлы (с разделителями табуляции)» Кодировка — Windows-1251, разделители — табуляция, переводы строк — 0×0D, 0×0A. Значение «01;02» помещено в кавычки (без особой нужды). Объем файла — 110 байт

Какой вывод мы делаем из этого?.. То, что здесь Microsoft называет «CSV (разделители — запятые)», на самом деле является форматом с разделителями «точка с запятой». Формат у Microsoft — строго Windows-1251. Поэтому, если у вас в Excel есть Unicode-символы, они на выходе в CSV отобразятся в вопросительные знаки. Также то, что переводами строк является всегда пара символов, то, что Microsoft тупо берет в кавычки все, где видит точку с запятой. Также то, что если у вас нет Unicode-символов вообще, то можно сэкономить на объеме файла. Также то, что Unicode поддерживается только UTF-16, а не UTF-8, что было бы сильно логичнее.

Теперь посмотрим, как на это смотрит Outlook. Попробуем импортировать эти файлы из него, указав такие же источники данных. Outlook 2007: Файл -> Импорт и экспорт… -> Импорт из другой программы или файла. Далее выбираем формат данных: «Значения, разделенные запятыми (Windows)» и «Значения, разделенные табуляцией (Windows)».

«Значения, разделенные табуляцией(Windows)» Скармливаем аутлуку файл tsv, с разделенными табуляцией значениями и!.. — чтобы вы думали?.. Outlook склеивает поля и табуляцию не замечает. Заменяем в файле табуляцию на запятые и, как видим, поля уже разбирает, молодец.
«Значения, разделенные запятыми (Windows)» А вот аутлук как раз понимает все верно. Comma — это запятая. Поэтому ожидает в качестве разделителя запятую. А у нас после экселя — точка с запятой. В итоге аутлук распознает все неверно.

Два майкрософтовских продукта не понимают друг друга, у них напрочь отсутствует возможность передать через текстовый файл структурированные данные. Для того, чтобы все заработало, требуются «пляски с бубном» программиста.

Мы помним, что Microsoft Excel умеет работать с текстовыми файлами, импортировать данные из CSV, но в версии 2007 он делает это очень странно. Например, если просто открыть файл через меню, то он откроется без какого-либо распознавания формата, просто как текстовый файл, целиком помещенный в первую колонку. В случае, если сделать дабл-клик на CSV, Excel получает другую команду и импортирует CSV как надо, не задавая лишних вопросов. Третий вариант — вставка файла на текущий лист. В этом интерфейсе можно настраивать разделители, сразу же смотреть, что получилось. Но одно но: работает это плохо. Например, Excel при этом не понимает закавыченных переводов строк внутри полей.

Более того, одна и та же функция сохранения в CSV, вызванная через интерфейс и через макрос, работает по-разному. Вариант с макросом не смотрит в региональные настройки вообще.

Стандарта CSV как такового, к сожалению, нет, но, между тем, существует т.н. memo. Это RFC 4180

2005-го

года, в котором описано все довольно толково. За неимением ничего большего, правильно придерживаться хотя бы RFC. Но для совместимости с Excel следует учесть его собенности.

Вот краткая выжимка рекомендаций RFC 4180 и мои комментарии в квадратных скобках:

  • между строками — перевод строки CRLF [на мой взгляд, им не стоило ограничивать двумя байтами, т.е. как CRLF (0×0D, 0×0A), так и CR 0×0D]
  • разделители — запятые, в конце строки не должно быть запятой,
  • в последней строке CRLF не обязателен,
  • первая строка может быть строкой заголовка (никак не помечается при этом)
  • пробелы, окружающие запятую-разделитель, игнорируются.
  • если значение содержит в себе CRLF, CR, LF (символы-разделители строк), двойную кавычку или запятую (символ-разделитель полей), то заключение значения в кавычки обязательно. В противном случае — допустимо.
  • т.е. допустимы переводы строк внутри поля. Но такие значения полей должны быть обязательно закавычены,
  • если внутри закавыченной части встречаются двойные кавычки, то используется специфический квотинг кавычек в CSV — их дублирование.

Вот в нотации ABNF описание формата:

 file = [header CRLF] record *(CRLF record) [CRLF]
   header = name *(COMMA name)
   record = field *(COMMA field)
   name = field
   field = (escaped / non-escaped)
   escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
   non-escaped = *TEXTDATA
   COMMA = %x2C
   DQUOTE =  %x22
   LF = %x0A
   CRLF = CR LF
   TEXTDATA =  %x20-21 / %x23-2B / %x2D-7E
 

Также при реализации формата нужно помнить, что поскольку здесь нет указателей на число и тип колонок, поскольку нет требования обязательно размещать заголовок, здесь есть условности, о которых необходимо не забывать:

  • строковое значение из цифр, не заключенное в кавычки может быть воспринято программой как числовое, из-за чего может быть потеряна информация, например, лидирующие нули,
  • количество значений в каждой строке может отличаться и необходимо правильно обрабатывать эту ситуацию. В одних ситуациях нужно предупредить пользователя, в других — создавать дополнительные колонки и заполнять их пустыми значениями. Можно определиться, что количество колонок задается заголовком, а можно добавлять их динамически, по мере импорта CSV,
  • Квотить кавычки через «слэш» не по стандарту, делать так не надо.
  • Поскольку типизации полей нет, нет и требования к ним. Разделители целой и дробной частей в разных странах разные, и это приводит к тому, что один и тот же CSV, сгенрированный приложением, в одном экселе «понимается», в другом — нет. Потому что Microsoft Office ориентируется на региональные настройки Windows, а там может быть что угодно. В России там указано, что разделитель — запятая,
  • Если CSV открывать не через меню «Данные», а напрямую, то Excel лишних вопросов не задает, и делает как ему кажется правильным. Например, поле со значением 1.24 он понимает по умолчанию как «24 января»
  • Эксель убивает ведующие нули и приводит типы даже тогда, когда значение указано в кавычках. Делать так не надо, это ошибка. Но чтобы обойти эту проблему экселя, можно сделать небольшой «хак» — значение начать со знака «равно», после чего поставить в кавычках то, что необходимо передать без изменения формата.
  • У экселя есть спецсимвол «равно», который в CSV рассматривается как идентификатор формулы. То есть, если в CSV встретится =2+3, он сложит два и три и результат впишет в ячейку. По стандарту он это делать не должен.

Пример валидного CSV, который можно использовать для тестов:

Фамилия, Имя, Адрес, Город/штат, индекс, просто строка
Иванов,Иван, Ленина 20, Москва, 08075, "1/3"
Tyler, John,110 terrace, PA,20121, "1.24"
"Петров 
""Кул""", Петя,120 Hambling St., NJ,08075, "1,24"
Смирнов,Вася,"7452 Street ""Near the Square"" road", York, 91234, "3-01"
,Миша,,Ленинград, 00123, "03-01"
"Джон ""Черная голова"", Клод",Рок,"", Маями бич,00111, "0000"
Сергей,,

точно такой же SCSV:

Фамилия; Имя; Адрес;  Город/штат; индекс; просто строка
Иванов;Иван; Ленина 20; Москва; 08075;"1/3"
Tyler; John;110 terrace; PA; 20121;"1.24"
"Петров 
""Кул"""; Петя;120 Hambling St.; NJ;08075;"1,24"
Смирнов;Вася;"7452 Street ""Near the Square"" road"; York; 91234;"3-01"
;Миша;;Ленинград; 00123;"03-01"
"Джон ""Черная голова""; Клод";Рок;""; Маями бич;00111; "0000"
Сергей;;

Первый файлик, который реально COMMA-SEPARATED, будучи сохраненным в .csv, Excel-ом не воспринимается вообще.

Второй файлик, который по логике SCSV, экселом воспринимается и выходит вот что:

Ошибки Excel-я при импорте:

  1. Учлись пробелы, окружающие разделители
  2. Последний столбец вообще толком не распознался, несмотря на то, что данные в кавычках. Исключение составляет строка с «Петровым» — там корректно распозналось 1,24.
  3. В поле индекс Excel «опустил» ведущие нули.
  4. в самом правом поле последней строки пробелы перед кавычками перестали указывать на спецсимвол

Если же воспользоваться функционалом импорта (Данные -> Из файла) и обозвать при импорте все поля текстовыми, то будет следующая картина:

С приведением типов сработало, но зато теперь не обрабатываются нормально переводы строк и осталась проблема с ведущими нулями, кавычками и лишними пробелами. Да и пользователям так открывать CSV крайне неудобно.

Есть эффективный способ, как заставить Excel не приводить типы, когда это нам не нужно. Но это будет CSV «специально для Excel». Делается это помещением знака «=» перед кавычками везде, где потенциально может возникнуть проблема с типами. Заодно убираем лишние пробелы.

Фамилия;Имя;Адрес;Город/штат;индекс;просто строка
Иванов;Иван;Ленина 20;Москва;="08075";="1/3"
Tyler; John;110 terrace;PA;="20121";="1.24"
"Петров 
""Кул""";Петя;120 Hambling St.;NJ;="08075";="1,24"
Смирнов;Вася;"7452 Street ""Near the Square"" road";York;="91234";="3-01"
;Миша;;Ленинград;="00123";="03-01"
"Джон ""Черная голова"";Клод";Рок;"";Маями бич;="00111";="0000"
Сергей;;

И вот что случаеся, если мы открываем этот файлик в экселе:

Резюмирую.

Чтобы сгенерировать такой CSV, которым можно было бы пользоваться, пользователю нужно дать возможность сделать следующие настройки перед экспортом:

  1. выбрать кодировку. Как правило, важно UTF-8, UTF-16, Windows-1251, KOI8-R. Чаще всего, других вариантов нет. Одна из них должна идти по умолчанию. В случае, если данные содержат символы, не имеющие аналогов в целевой кодировке, нужно предупреждать пользователя, что данные будут битые;
  2. выбрать разделитель между полями. Варианты — табуляция, запятая, точка с запятой. По умолчанию — точка с запятой. Не забыть, что если разделитель вводится в тексте, то будет очень непросто ввести туда табуляцию, это еще и непечатный символ;
  3. выбрать разделитель между строками (CRLF 0×0D 0×0A или CR 0×0D);
  4. выбрать разделитель целой и дробной части для числовых данных (точка или запятая).
  5. выбрать, выводить ли строку заголовка;
  6. выбрать, каким образом осуществлять квотинг спецсимволов (особенно переводов строк и кавычек). В принципе, можно отступиться от стандарта и квотировать их как n и «, но нужно в этом случае не забыть квотировать сами n, если они встретятся и не забыть сделать это опцией при экспорте-импорте. Но совместимость пойдет лесом, потому что любой RFC-стандартный парсер конструкцию …,»abc«»,… посчитает за ошибку;
  7. совсем в идеале — поставить галочку «для Excel» и учитывать там те нестандартности, которые внесла Майкрософт. К примеру, заменять значения числовых полей, «похожих на дату», на конструкцию =»<значение поля>«.
  8. определиться, нужно ли оставлять «хвост» из пустых разделителей, если он образуется. Например, из 20 полей только первое содержит данные, а остальные пустые. В итоге, в строке можно либо ставить после первого 19 разделителей, либо не ставить. Для больших объемов данных это может спасти миллисекунды обработки и уменьшить размер файла.

Чтобы построить хороший и удобный импортер CSV, необходимо помнить о следующем:

  1. разбор файла нужно делать по лексемам в соответствии с грамматикой выше или пользоваться хорошо зарекомендовавшими себя готовыми библиотеками (Excel работает иначе, потому с импортом проблема);
  2. предоставлять пользователю возможность выбрать кодировку (топ 4 достаточно);
  3. предоставлять пользователю возможность выбрать разделитель между полями (запятая, табуляция, точка с запятой достаточно);
  4. предоставлять пользователю возможность выбрать разделитель между строками, но кроме вариантов CR и CRLF нужно предусмотреть «CR или CRLF». Это связано с тем, что, например, Excel при экспорте таблицы с переводами строк внутри ячеек экспортирует эти переводы строк как CR, а остальные строки разделяет CRLF. При этом при импорте файла ему все равно, CR там или CRLF;
  5. предоставлять пользователю возможность выбрать разделитель между целой и дробной частей (запятая или точка);
  6. определиться с методом разбора — сначала читаем все в память, потом обрабатываем или обрабатываем строку за строкой. В первом случае может понадобиться больше памяти, во втором случае — ошибка в середине вызовет только частичный импорт, что может вызвать проблемы. Предпочительнее первый вариант.

Рауф Алиев,
заместитель технического директора Mail.Ru Group

Понравилась статья? Поделить с друзьями:
  • Ошибка при иммобилизации всей нижней конечности лестничными шинами
  • Ошибка при измерении пульса mi band 4
  • Ошибка при измерении линии не должна превышать
  • Ошибка при измерении давления которую делают все
  • Ошибка при измерении давления err cuf