запись в фаил csv и экранирование " для нормального просмотра в экселе с хаком

Petrrrr

Новичок
гуруПХП подскажите как можно экранировать " для того чтобы нормально можно было просмотреть в эселе фаил csv

вот пример
<?php
$name = 'блабла бла" ловатлом';
$name2 = 'бррр,рррр';
$feature = 'slvfjkdnvkn';
$fp = fopen('/exprt.csv', 'w'); //создаю фаил;
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) )); //хак для экселя
$csv_file = '"'.$name.'";"'.$name2.'";"'.$feature.'";'."\r\n"; //собираю данные
fwrite($fp,$csv_file); // записываю
$csv_file = '"'.$name2.'";"'.$name.'";"'.$feature.'";'."\r\n";
fwrite($fp,$csv_file); // записываю
fclose($fp); // закрываю
?>
и вот эта " в $name, в экселе либо гуляет где попало, либо ломает разбиение по ячейкам

что можно сделать удалять эти " или как можно их экранировать для экселя?
 

Petrrrr

Новичок
$name = str_replace('"', '""', $name);
то есть " само себя будет экранировать?
а подскажите какие еще могут быть символы в литературном тексте которые могут нарушить структуру этого файла, ну кроме тех которые можно закрыть trim()
 

Фанат

oncle terrible
Команда форума
trim() не помогает "закрыть символы", если что.

Я не помню, как эксель реагирует на переводы строк, но возможно их тоже желательно удалять из данных
 

fixxxer

К.О.
Партнер клуба
да спасибо, я знаю, но она мне не подходит, там много нюансов
Подходит-подходит.

Во-первых, никто не мешает комбирировать fputcsv() и fwrite().
Во-вторых, если даже все совсем сложно, можно ее использовать и для форматирования csv в памяти, примерно так:

PHP:
function array_to_csv(array $data) {
    $buffer = fopen('php://memory', 'r+');
    fputcsv($buffer, $data);
    rewind($buffer);
    $result = stream_get_contents($buffer);
    fclose($buffer);
    return $result;
}
 

Petrrrr

Новичок
Подходит-подходит.

Во-первых, никто не мешает комбирировать fputcsv() и fwrite().
Во-вторых, если даже все совсем сложно, можно ее использовать и для форматирования csv в памяти, примерно так:

PHP:
function array_to_csv(array $data) {
    $buffer = fopen('php://memory', 'r+');
    fputcsv($buffer, $data);
    rewind($buffer);
    $result = stream_get_contents($buffer);
    fclose($buffer);
    return $result;
}
я понимаю что вы гуру, но для меня процесс усложнится в разы

а в эту конструкцию можно будет внедрить fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) )); ?

там еще в процессе сборки данных идет переборка нескольких массивов со всякими проверками и дополнениями
мне проще видеть строку которую я планирую записать

но все равно спасибо за подсказку, подробнее изучу работу в памяти


trim() не помогает "закрыть символы", если что.

Я не помню, как эксель реагирует на переводы строк, но возможно их тоже желательно удалять из данных
в экселе перенос также создает переренос на новую строку, вот я от него и избавляюсь

и тогда подскажите если планируется записать примерно от 300000 строк и более, предварительно поработав с ними
как способ менее затратный?
 

fixxxer

К.О.
Партнер клуба
а в эту конструкцию можно будет внедрить fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) )); ?

там еще в процессе сборки данных идет переборка нескольких массивов со всякими проверками и дополнениями
мне проще видеть строку которую я планирую записать
Ну не проблема совсем.
PHP:
$name = 'блабла бла" ловатлом';
$name2 = 'бррр,рррр';
$feature = 'slvfjkdnvkn';
$fp = fopen('/exprt.csv', 'w'); //создаю фаил;
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) )); //хак для экселя
$csv_file = [$name, $name2, $feature]; //собираю данные
fputcsv($fp,$csv_file); // записываю
$csv_file = [$name2, $name, $feature];
fputcsv($fp,$csv_file); // записываю
fclose($fp); // закрываю
 

fixxxer

К.О.
Партнер клуба
В текущей постановке вопроса этого недостаточно, надо же переопределить делимитер и экранирующий символ
Задача:
чтобы нормально можно было просмотреть в эселе фаил csv
Стандартный разделитель для екселя - как раз запятая. А экранирование кавычки удвоением - по умолчанию.
 

AnrDaemon

Продвинутый новичок
Эксель экспортирует с ";", но на входе понимает почти любые разделители.
И вообще, почему никто до сих пор не упомянул http://php.net/splfileobject ?
 

AnrDaemon

Продвинутый новичок
Ладно, хорошо, он экспортирует с разделителем списков. При чём тут десятичный разделитель?
 

fixxxer

К.О.
Партнер клуба
Есть подозрение, что разделитель списка по дефолту точка с запятой на тех локалях, где десятичный разделитель запятая.

Но вообще это пофигу, ну хочет через точку с запятой, ну добавит аргумент в fputcsv, какая нафиг разница?
 

Petrrrr

Новичок
господа не входите в полемику!
я вспомнил почему не пользуюсь fputcsv
  1. эта функция делает тоже что и я тоесть разбирает массив в строку и записывает построчно fwrite (возможно я не прав)
  2. я сам создал свою функцию записи в фаил со своими правилами, делителями и ограничениями
  3. у меня там есть массивы у которых есть вложенные массивы которые могут быть пустыми, то есть мне нужно собрать массив в fputcsv из всего этого и чтобы столбцы с пустыми значениями не сдвигались, сложно, проще собрать строку и вместо пустого места вставить сразу делитель ';' тогда не будет смещения по столбцам (это все для экселя)
  4. только делитель ; с " " отлично отображает данные в эксель по ячейкам без всяких преобразований
  5. где то прочитал что fputcsv в каких то моментах может не оборачивать строку в " "
  6. и об этом слышал Использование php-функции fputcsv записывает только \n и не может быть настроено (но не уверен)
возможно я в чем-то не прав не ругайте сильно, буду впитывать все нравоучения
 

fixxxer

К.О.
Партнер клуба
у меня там есть массивы у которых есть вложенные массивы которые могут быть пустыми, то есть мне нужно собрать массив в fputcsv из всего этого и чтобы столбцы с пустыми значениями не сдвигались, сложно
Чего сложного? [$a1, $a2, "", $a4]. Не вижу никакой разницы.
только делитель ; с " " отлично отображает данные в эксель по ячейкам без всяких преобразований
fputcsv($fp, $csv_file, ";");
 
Сверху