Аватар пользователя Dima

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

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

Хочу поделиться этим простым классом и показать как его можно использовать.
Обращу ваше внимание, что класс работает под Drupal 6. Впрочем единственное отличие от его использования в простом PHP - это функция
drupal_set_header(), которая устанавливает HTTP заголовки текущей страницы. Чтобы исспользовать класс с
Druapal 7 нужно изменить drupal_set_header() на аналогичную для Drupal 7 - drupal_add_http_header().

Вот код самого класса:

  1. class CSV {
  2.  
  3. var $separator = "\t"; //string, string separator
  4. var $striptags = TRUE; //bool, striptags or no tags
  5.  
  6. /**
  7.   * @param array: Column headings
  8.   * @param array: Content to go in CSV
  9.   * @param string: Caption for table
  10.   *
  11.   * @return string: CSV format string from input
  12.   **/
  13. public function build($columns = NULL, $data = NULL, $tablecaption = NULL){
  14. $csv = ''; // initialise csv variable
  15. if($tablecaption){
  16. $csv .= $tablecaption . $this->separator;
  17. $csv .= "\n\n";
  18. }
  19. if($columns){
  20. // csv column headings
  21. foreach($columns as $heading){
  22. $csv .= ($this->striptags ? strip_tags($heading) : $heading) . $this->separator; // concat heading onto row
  23. }
  24. $csv .= "\n"; // all the headings have been added so move to new line for csv content
  25. }
  26. // csv table content
  27. if($data){
  28. foreach($data as $row){
  29. foreach($columns as $column => $t)
  30. {
  31. if(strpos($row[$column],$this->separator)) // if cell content has a comma in it...
  32. {
  33. // ...double any existing quotes to escape them...
  34. $row[$column] = str_replace('"','""',$row[$column]);
  35. // ...and wrap the cell in quotes so the comma doesn't break everything.
  36. $row[$column] = '"'.$row[$column].'"';
  37. }
  38. $csv .= ($this->striptags ? strip_tags($row[$column]) : $row[$column]) . $this->separator; // concat the value onto the row
  39. if($t==end($columns))
  40. {
  41. // if we're at the end of a row move to a new line for next row
  42. $csv .= "\n";
  43. }
  44. }
  45. }
  46. $csv .= "\n";
  47. }
  48. return $csv;
  49. }
  50.  
  51. /**
  52.   * @param string: String in CSV format
  53.   * @param string: optional - File name to save CSV as
  54.   *
  55.   * @return void
  56.   **/
  57. public function save($csv, $file_name = null)
  58. {
  59. // if no file name is provided set the file name to todays date
  60. if(!$file_name){
  61. $file_name = date('Y-m-d');
  62. }
  63. // set content type and file name then output csv content
  64. drupal_set_header("Content-type: text/csv; charset=UTF-8");
  65. drupal_set_header("Content-Disposition: attachment; filename=\"$file_name.csv\"");
  66. drupal_set_header('Pragma: no-cache');
  67. drupal_set_header('Expires: 0');
  68.  
  69. $csv = iconv("UTF-8", "UTF-16LE", $csv);
  70. $csv = chr(hexdec('FF')) . chr(hexdec('FE')) . $csv;
  71.  
  72. echo $csv;
  73. }
  74. }

Покажу несколько примеров как его можно использовать для экспорта данных в CSV формат.

  1. Экспорт данных в виде простой таблицы:
    Класс принимает данные в похожей манере со стандартной функцией Drupal theme_table().
    1. $header = array(t('Col 1'), t('Col 2'), t('Col 3'));
    2. $data = array(
    3. array('row 1', 'row 1', 'row 1'),
    4. array('row 2', 'row 2', 'row 2'),
    5. array('row 3', 'row 3', 'row 3'),
    6. );
    7.  

    Также можно установить не обязательный параметр $tablecaption, в который можно выводить заголовок таблицы.
    1. $tablecaption = "tablecaption";
    2.  

    Генерация и вывод простой таблицы будет выглядеть примерно следующим образом:
    1. include_once "tocsv.inc";
    2. $columns = array(t('Col 1'), t('Col 2'), t('Col 3'));
    3. $data = array(
    4. array('row 1', 'row 1', 'row 1'),
    5. array('row 2', 'row 2', 'row 2'),
    6. array('row 3', 'row 3', 'row 3'),
    7. );
    8. $tablecaption = "tablecaption";
    9. $csv = new CSV();
    10. $csv_string = "";
    11. $csv_string .= $csv->build($columns, $data, $tablecaption);
    12. $file_name = "file_name";
    13. // output file
    14. $csv->save($csv_string, $file_name);
    15.  

    А что если нужно вывести в одном файле 2 таблицы с произвольной надписью между ними? Ничего сложного, следующий код покажет как это
    сделать:
    1. $csv = new CSV();
    2. $csv->striptags = FALSE;
    3. $csv_string = "";
    4. $columns = array(t('Col 1'), t('Col 2'), t('Col 3'));
    5. $data = array(
    6. array('row 1', 'row 1', 'row 1'),
    7. array('row 2', 'row 2', 'row 2'),
    8. array('row 3', 'row 3', 'row 3'),
    9. );
    10. $tablecaption = "tablecaption";
    11. $csv_string .= $csv->build($columns, $data, $tablecaption);
    12.  
    13. // add string
    14. $csv_string .= $csv->build(array('Date'), " ".date("d.m.Y", time())." "));
    15. $csv_string .= "\n";
    16.  
    17. // add another table
    18. $csv_string .= $csv->build($columns, $data, $tablecaption);
    19.  
    20. $file_name = 'file_name';
    21. // output file
    22. $csv->save($csv_string, $file_name);
    23.  

    Создаваемый классом объект имеет 2 свойства:
    separator и striptags.
    separator - устанавливает строку-разделитель, по умолчанию символ табуляции.
    striptags - булевое значение, устанавливает следует ли очищать данные перед экспортом от тегов.
    Класс корректно выводит utf-8 для Excel.