Генерируем правильный CSV

Под "правильным" CSV-файлом будем понимать такой, который корректно откроется в экселе по двойному клику мышью. Ведь довольно часто оказывется так, что файлы "разваливаютсся" при открытии и приходится их импортировать, как текстовые данные, что довольно сильно раздражает,  а для некоторых пользователей и вовсе может оказаться непосильной задачей. Секрет довольно прост - файл должен отвечать следующим требованиям:

  1. Разделитель - точка с запятой
  2. Кодировка Windows-1251

С первым, казалось бы, всё просто, но нет же - на Windows некоторые файлы могут открываться некорректно, если в первой строке не указать явно sep=;

Со вторым, казалось бы, тоже всё просто, но из-за кодировки придётся отказаться от функции fputcsv() и формировать строки из массива "вручную", например, с помощью implode(), затем переводить их в нужную кодировку и только затем записывать строку в файл. Всё из-за того, что fputcsv() берёт массив и пишет его сразу в файл в кодировке utf-8. Естественно, проблема не в стандартной функции PHP, а в идиотах из майкрософт, которые плюют на все стандарты и суют всюду свою дурацкую кодировку Windows-1251.

В итоге, код, записывающий некий двумерный массив $rows в csv будет выглядеть приблизительно так:

<?php
 $outputBuffer
= fopen($path, 'w');
   
fwrite($outputBuffer, "sep=;" . PHP_EOL);
    foreach(
$rows as $key => $val) {     
     
$line = "\"" . implode("\";\"", $val) . "\"" . PHP_EOL;
     
$line = mb_convert_encoding($line, 'windows-1251', 'UTF-8');
     
fwrite($outputBuffer, $line);
      unset(
$rows[$key]);      
    }
   
fclose($outputBuffer);
?>

Как видно, используется unset элемента массива после его записи в файл - это нужно для того, счтобы освободить память при работе с большим объёмом данных.

Никогда не используйте CSV-формат без крайней необходимости!

Лично я вряд ли смогу назвать более неудачный формат обмена данными, чем CSV. На это есть две причины:

  1. CSV совершенно никаким образом не подддерживает целостность данных и не сигнализирует, если они повреждены. Например, если при скачивании csv-файла произойдёт обрыв связи, вы так и не узнаете об этом, файл откроется, но в нём будет только часть записей, а вы в истерике будете биться головой об стену, не понимая, куда делось 90% товаров из вашего каталога.
  2. CSV может самопроизвольно "разваливаться", если в данных присутствуют кавычки, знаки табуляции или перевода строк. В частности, если одна из колонок CSV содержит длинный текст в HTML, то можно даже не пытаться открывать такой файл - колонки развалятся в любом случае.

Правильными альтернативами будут XML и JSON для передачи данных из одной систему в другую автоматически, а также XLS и XSLX для тех случаев, где данные предназначены для использования оператором. XML и JSON обрабатываются встроенными функциями PHP, а для работы с XLS и XSLX надо использовать библиотеку PHPExcel.

Когда использовать CSV всё-таки можно

Использование CSV может быть оправдано только в том случае, если нужно выгружать очень большой объём данных (десятки тысяч записей) в файл, который в дальнейшем будет обрабатываться оператором (человеком). Дело в том, что при использовании PHPExcel потребление ресурсов сервером значительно увеличивается по сравнению с работой с CSV , поэтому выбор CSV может быть продиктован аппаратными возможностями сервера.

Но для передачи данных напрямую из одной системы в другую использование CSV допустимо лишь в том случае, если вы идиот.

Поделиться: