Создание и Чтение CSV Файлов на PHP

Создание и Чтение CSV Файлов на PHP

CSV — это очень удобный формат для создания файлов, так как он имеет простую структуру. В этой статье мы узнаем, как устроены файлы с расширением .csv, как их создать и как считать на PHP. Сделать это очень просто!

Содержание

  • Формат CSV
  • Создание CSV файла на PHP
  • Чтение CSV файла на PHP
  • Конвертация .lsx, .xlsx файлов в .csv
  • Как предоставить сгенерированный CSV файл для скачивания

Формат CSV

Чтобы понять, как работать с CSV, нужно знать его спецификации. Вот краткая информация:

  • CSV (Comma-Separated Values) — это текстовый формат для представления табличных данных.
  • Каждая строка файла соответствует одной строке таблицы.
  • Разделитель значений в колонках — это символ , (в английском) или ; (в русском), так как запятая используется в десятичных дробях.
  • Значения, содержащие зарезервированные символы: ", ;, rn, n, или r (двойные кавычки, запятая, точка с запятой, переход на новую строку) обрамляются двойными кавычками ".
  • Если в значении есть двойные кавычки ", их необходимо записать как две подряд идущие двойные кавычки "".
  • Строки в файле могут разделяться символами rn или n.

Примеры

Пример для русского языка:

1965;Пиксель;E240 – формальдегид (опасный консервант)!;"красный, зелёный, битый";3000,00
1965;Мышка;"А правильней использовать ""Ёлочки""";;4900,00
"Н/д";Кнопка;Сочетания клавиш;"MUST USE! Ctrl, Alt, Shift";4799,00

Пример для английского языка:

1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture «Extended Edition»","",4900.00
1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00

Создание CSV файла на PHP

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

Код ��ля создания CSV файла

/**
 * Создает CSV файл из предоставленного массива данных.
 *
 * @param array  $create_data   Массив данных для создания CSV файла.
 * @param string $file          Путь к файлу 'path/to/test.csv'. Если не указан, результат будет возвращен.
 * @param string $col_delimiter Разделитель колонок. По умолчанию: ;.
 * @param string $row_delimiter Разделитель строк. По умолчанию: rn.
 *
 * @return false|string CSV строка или false, если не удалось создать файл.
 *
 * @version 2
 */
function kama_create_csv_file( $create_data, $file = null, $col_delimiter = ';', $row_delimiter = "rn" ){

    if( ! is_array( $create_data ) ){
        return false;
    }

    if( $file && ! is_dir( dirname( $file ) ) ){
        return false;
    }

    $CSV_str = '';

    foreach( $create_data as $row ){
        $cols = array();

        foreach( $row as $col_val ){
            if( $col_val && preg_match('/[",;rn]/', $col_val) ){
                if( $row_delimiter === "rn" ){
                    $col_val = str_replace( [ "rn", "r" ], [ 'n', '' ], $col_val );
                }
                elseif( $row_delimiter === "n" ){
                    $col_val = str_replace( [ "n", "rr" ], 'r', $col_val );
                }

                $col_val = str_replace( '"', '""', $col_val ); 
                $col_val = '"'. $col_val .'"'; 
            }

            $cols[] = $col_val; 
        }

        $CSV_str .= implode( $col_delimiter, $cols ) . $row_delimiter; 
    }

    $CSV_str = rtrim( $CSV_str, $row_delimiter );

    if( $file ){
        $CSV_str = iconv( "UTF-8", "cp1251",  $CSV_str );
        $done = file_put_contents( $file, $CSV_str );
        return $done ? $CSV_str : false;
    }

    return $CSV_str;
}

// Пример использования:
$create_data = array(
    array('Заголовок 1', 'Заголовок 2', 'Заголовок 3'),
    array('строка 2 "колонка 1"', '4799.01', 'строка 2 "колонка 3"'),
    array('"Ёлочки"', 4900.01, 'красный, зелёный')
);

echo kama_create_csv_file( $create_data, 'csv_file.csv' );

Чтение CSV файла на PHP

Чтобы получить данные из CSV файла, т.е. разобрать его и получить данные в массив, можно использовать встроенную функцию PHP str_getcsv().

Код для чтения CSV файла

/**
 * Читает CSV файл и возвращает данные в виде массива.
 *
 * @param string $file_path      Путь к CSV файлу.
 * @param array  $file_encodings Кодировки файла
 * @param string $col_delimiter  Разделитель колонок (по умолчанию определяется автоматически)
 * @param string $row_delimiter  Разделитель строк (по умолчанию определяется автоматически)
 *
 * @version 6
 */
function kama_parse_csv_file( $file_path, $file_encodings = ['cp1251','UTF-8'], $col_delimiter = '', $row_delimiter = '' ){

    if( ! file_exists( $file_path ) ){
        return false;
    }

    $cont = trim( file_get_contents( $file_path ) );
    $encoded_cont = mb_convert_encoding( $cont, 'UTF-8', mb_detect_encoding( $cont, $file_encodings ) );

    unset( $cont );

    if( ! $row_delimiter ){
        $row_delimiter = "rn";
        if( false === strpos($encoded_cont, "rn") )
            $row_delimiter = "n";
    }

    $lines = explode( $row_delimiter, trim($encoded_cont) );
    $lines = array_filter( $lines );
    $lines = array_map( 'trim', $lines );

    if( ! $col_delimiter ){
        $lines10 = array_slice( $lines, 0, 30 );
        foreach( $lines10 as $line ){
            if( ! strpos( $line, ',') ) $col_delimiter = ';';
            if( ! strpos( $line, ';') ) $col_delimiter = ',';
            if( $col_delimiter ) break;
        }

        if( ! $col_delimiter ){
            $delim_counts = array( ';'=>array(), ','=>array() );
            foreach( $lines10 as $line ){
                $delim_counts[','][] = substr_count( $line, ',' );
                $delim_counts[';'][] = substr_count( $line, ';' );
            }

            $delim_counts = array_map( 'array_filter', $delim_counts );
            $delim_counts = array_map( 'array_count_values', $delim_counts );
            $delim_counts = array_map( 'max', $delim_counts );

            if( $delim_counts[';'] === $delim_counts[','] )
                return array('Не удалось определить разделитель колонок.');

            $col_delimiter = array_search( max($delim_counts), $delim_counts );
        }
    }

    $data = [];
    foreach( $lines as $key => $line ){
        $data[] = str_getcsv( $line, $col_delimiter ); 
        unset( $lines[$key] );
    }

    return $data;
}

// Пример использования:
$data = kama_parse_csv_file( 'file.csv' );
print_r( $data );

Конвертация .LSX, .XLSX файлов в .CSV

Чтобы конвертировать Excel файл в CSV, откройте его в Excel и сохраните в формате .csv.

Если вам нужно сделать это программно, обратитесь к онлайн конвертерам с API или готовым библиотекам.

Как предоставить сгенерированный CSV файл для скачивания

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

header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename="file.csv"' );

$create_data = [
    ['Заголовок 1', 'Заголовок 2', 'Заголовок 3'],
];

echo kama_create_csv_file( $create_data );

Теперь вы знаете, как работать с CSV файлами на PHP! Если у вас есть вопросы или замечания, не стесняйтесь делиться ими в комментариях.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *