Advertisement
Guest User

cricket

a guest
Apr 1st, 2010
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.04 KB | None | 0 0
  1. <?php
  2. /**
  3.  * CSV helper for cakePHP.
  4.  *
  5.  * PHP version 5
  6.  *
  7.  * Licensed under The MIT License
  8.  *
  9.  * @copyright   Adam Royle
  10.  * @license     http://www.opensource.org/licenses/mit-license.php The MIT License
  11.  * @link        http://bakery.cakephp.org/articles/view/csv-helper-php5
  12.  */
  13. class CsvHelper extends AppHelper
  14. {
  15.     public $delimiter = ',';
  16.     public $enclosure = '"';
  17.     public $clean_output = true;
  18.    
  19.     /* This option preserves leading zeros on numeric data when opened in Excel.
  20.      * Use it ONLY when the csv file is going to be opened in Excel, as it uses
  21.      * non-standard syntax, and will probably break in other systems.
  22.      */
  23.     public $preserveLeadingZerosInExcel = false;
  24.    
  25.     private $line = array();
  26.     private $buffer;
  27.     private $filename = 'export.csv';
  28.     private $trans_tbl = null;
  29.    
  30.     public function CsvHelper()
  31.     {
  32.         $this->clear();
  33.     }
  34.    
  35.     /**
  36.      * Clears internal buffer. This is called automatically by CsvHelper::render()
  37.      *
  38.      * @access public
  39.      */
  40.     public function clear()
  41.     {
  42.         $this->line = array();
  43.         $this->buffer = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
  44.     }
  45.    
  46.     /**
  47.      * Adds a single field value to the buffer. You must call $csv->endRow() to commit fields to the buffer.
  48.      *
  49.      * @param string $value Field value
  50.      * @access public
  51.      */
  52.     public function addField($value)
  53.     {
  54.         $this->line[] = ($this->clean_output ? $this->cleanStr($value) : $value);
  55.     }
  56.  
  57.     /**
  58.      * Commits the row of fields that were added by addField()
  59.      *
  60.      * @access public
  61.      */
  62.     public function endRow()
  63.     {
  64.         $this->addRow($this->line);
  65.         $this->line = array();
  66.     }
  67.    
  68.    
  69.     /**
  70.      * Adds a single row to the buffer.
  71.      *
  72.      * @param array $row Data to be added
  73.      * @access public
  74.      */
  75.     public function addRow($row)
  76.     {
  77.         if ($this->clean_output)
  78.         {
  79.             $row = $this->cleanStr($row);
  80.         }
  81.        
  82.         if ($this->preserveLeadingZerosInExcel)
  83.         {
  84.             /* convert the number to a string formula
  85.              */
  86.             foreach ($row as $key => $value)
  87.             {
  88.                 if (strlen($value) > 1 && $value[0] == '0' && is_numeric($value))
  89.                 {
  90.                     $row[$key] = '="'.$value.'"';
  91.                 }
  92.             }
  93.         }
  94.         fputcsv($this->buffer, $row, $this->delimiter, $this->enclosure);
  95.     }
  96.    
  97.    
  98.     /**
  99.      * Adds a multi-dimensional array to the buffer.
  100.      *
  101.      * @param array $data Multi-dimensional array
  102.      * @param boolean $addFieldNames Add a row of field names before adding data
  103.      * @access public
  104.      */
  105.     function addGrid($data, $addFieldNames = true, $fieldList = null)
  106.     {
  107.         if (!$data)
  108.         {
  109.             return false;
  110.         }
  111.        
  112.         if (@is_array(reset($row = reset($data))))
  113.         {
  114.            
  115.             /* Array generated by cakePHP model
  116.              * eg.
  117.              * $data = array(
  118.              *     array(
  119.              *        'Model' => array('field_name' => 'field value')
  120.              *      ),
  121.              *      array(
  122.              *         'Model' => array('field_name' => 'field value')
  123.              *      )
  124.              * )
  125.              */        
  126.             $defaultModel = key($row);
  127.             if ($this->filename === null)
  128.             {
  129.                 $this->setFilename(Inflector::pluralize($defaultModel));
  130.             }
  131.            
  132.             if ($fieldList)
  133.             {
  134.                 $fields = array();
  135.                
  136.                 foreach ($fieldList as $fieldName)
  137.                 {
  138.                     if (strpos($fieldName, '.'))
  139.                     {
  140.                         list($modelName, $fieldName) = explode('.', $fieldName);
  141.                     }
  142.                     else
  143.                     {
  144.                         $modelName = $defaultModel;
  145.                     }
  146.                     $fields[] = array(Inflector::humanize($modelName), $fieldName);
  147.                 }
  148.                
  149.                 if ($addFieldNames)
  150.                 {
  151.                     foreach ($fields as $field)
  152.                     {
  153.                         if ($field[0] != $defaultModel)
  154.                         {
  155.                             $this->addField($field[0].' '.Inflector::humanize($field[1]));
  156.                         }
  157.                         else
  158.                         {
  159.                             $this->addField(Inflector::humanize($field[1]));
  160.                         }
  161.                     }
  162.                     $this->endRow();
  163.                 }
  164.                
  165.                 foreach ($data as $row)
  166.                 {
  167.                     foreach ($fields as $field)
  168.                     {
  169.                         @$this->addField($row[$field[0]][$field[1]]);
  170.                     }
  171.                     $this->endRow();
  172.                 }
  173.                
  174.             }
  175.             else
  176.             {
  177.                 if ($addFieldNames)
  178.                 {
  179.                     foreach (reset($row) as $key => $value)
  180.                     {
  181.                         $this->addField(Inflector::humanize($key));
  182.                     }
  183.                     $this->endRow();
  184.                 }
  185.                
  186.                 foreach ($data as $row)
  187.                 {
  188.                     $this->addRow($row[$defaultModel]);
  189.                 }
  190.             }
  191.            
  192.         }
  193.         else
  194.         {
  195.             /* Regular 2-dimensional array (with or without keys).
  196.              * eg.
  197.              * $data = array(
  198.              *     array('field_name' => 'field_value'),
  199.              *     array('field_name' => 'field_value')
  200.              * )
  201.              * or
  202.              * $data = array(array('field value'), array('field value'))
  203.              */        
  204.             if ($fieldList)
  205.             {              
  206.                 if ($addFieldNames)
  207.                 {
  208.                         foreach ($fieldList as $fieldName)
  209.                         {
  210.                             $this->addField(Inflector::humanize($fieldName));
  211.                         }
  212.                         $this->endRow();
  213.                 }
  214.                 foreach ($data as $row)
  215.                 {
  216.                     foreach ($fieldList as $fieldName)
  217.                     {
  218.                         @$this->addField($row[$fieldName]);
  219.                     }
  220.                     $this->endRow();
  221.                 }
  222.             }
  223.             else
  224.             {
  225.                 if ($addFieldNames)
  226.                 {
  227.                     foreach (reset($data) as $key => $value)
  228.                     {
  229.                         $this->addField(Inflector::humanize($key));
  230.                     }
  231.                     $this->endRow();
  232.                 }
  233.                 foreach ($data as $row)
  234.                 {
  235.                     $this->addRow($row);
  236.                 }
  237.             }
  238.         }
  239.     }
  240.    
  241.    
  242.     /**
  243.      * Clean strings up a bit before sending them to output
  244.      *
  245.      * @param   mixed   string or array of data
  246.      * @return  mixed   string or array of cleaned data
  247.      * @access  private
  248.      */
  249.     private function cleanStr($data)
  250.     {
  251.         $flatten = false;
  252.         if (!is_array($data))
  253.         {
  254.             $flatten = true;
  255.             $data = array($data);
  256.         }
  257.        
  258.         foreach ($data as $key => $datum)
  259.         {
  260.             if (is_string($datum))
  261.             {
  262.                 $datum = str_replace(array("\r", "\n", "\t"), ' ', trim($datum));
  263.                
  264.                 if (!empty($datum))
  265.                 {
  266.                     $data[$key] = strtr($datum, $this->getTransTable());
  267.                 }
  268.             }
  269.         }
  270.         return ($flatten ? $data[0] : $data);
  271.     }
  272.    
  273.    
  274.     /**
  275.      * Get the translation table used for entitites and special chars
  276.      *
  277.      * @param   void
  278.      * @return  mixed   the translation table array
  279.      * @access  private
  280.      */
  281.     private function getTransTable()
  282.     {
  283.         if (!is_null($this->trans_tbl)) return $this->trans_tbl;
  284.        
  285.         $ttr = get_html_translation_table(HTML_ENTITIES);
  286.        
  287.         foreach($ttr as $k => $v)
  288.         {
  289.             $this->trans_tbl[$v] = utf8_encode($k);
  290.         }
  291.        
  292.         return $this->trans_tbl;
  293.     }
  294.    
  295.    
  296.     /**
  297.      * Outputs headers
  298.      *
  299.      * @param string $filename Filename to save as
  300.      * @access public
  301.      */
  302.     public function renderHeaders($filename = null)
  303.     {
  304.         if (is_string($filename) && !empty($filename))
  305.         {
  306.             $this->setFilename($filename);
  307.         }
  308.        
  309.         header ('Expires: Mon, 1 Apr 1974 05:00:00 GMT');
  310.         header ('Last-Modified: ' . gmdate('D,d M YH:i:s') . ' GMT');
  311.         header ('Pragma: no-cache');
  312.         header('Content-disposition:attachment;filename='.$this->filename);
  313.         //header('Content-type:application/vnd.ms-excel');
  314.         //header('Content-type: application/vnd.ms-excel; charset=UTF-16LE');
  315.         header('Content-Type: application/csv');
  316.     }
  317.    
  318.     /**
  319.      * Sets the output filename. Automatically appends .csv if necessary.
  320.      *
  321.      * @param string $filename Filename to save as
  322.      * @access public
  323.      */
  324.     public function setFilename($filename)
  325.     {
  326.         if (!empty($filename))
  327.         {
  328.             if (strtolower(substr($filename, -4)) != '.csv')
  329.             {
  330.                 $filename .= '.csv';
  331.             }
  332.             $this->filename = $filename;
  333.         }
  334.     }
  335.    
  336.     /**
  337.      * Returns CSV string and clears internal buffer. Outputs headers() if necessary.
  338.      *
  339.      * @param mixed $outputHeaders Boolean to determine if should output headers, or a string to set the filename
  340.      * @param string $to_encoding Encoding to use
  341.      * @param string $from_encoding
  342.      * @return string String CSV formatted string
  343.      * @access public
  344.      */
  345.     public function render($outputHeaders = true, $to_encoding = null, $from_encoding = 'auto')
  346.     {
  347.         if ($outputHeaders)
  348.         {
  349.             if (is_string($outputHeaders))
  350.             {
  351.                 $this->setFilename($outputHeaders);
  352.             }
  353.             $this->renderHeaders();
  354.         }
  355.        
  356.         rewind($this->buffer);
  357.         $output = stream_get_contents($this->buffer);
  358.        
  359.         if ($to_encoding)
  360.         {
  361.             $output = mb_convert_encoding($output, $to_encoding, $from_encoding);
  362.         }
  363.         else
  364.         {
  365.             //$output = chr(255).chr(254).mb_convert_encoding($output, 'UTF-16LE', 'UTF-8');
  366.         }
  367.         return $this->output($output);
  368.     }
  369. }
  370. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement