phpcakephp

How to use cakephp export txt file


I'm using cakephp framework.I want to export a database table of a client download in two formats.One is '.csv', the other is a '.txt'.CSV which I have passed 'csvHelper' resolved.Now I want to know how to export '.txt'.Sorry for my poor English, but I think you'll see what I mean, thanks!


Solution

  • Basically you set the header for the filename, like this:

            $this->response->type('Content-Type: text/csv');
        $this->response->download('myfilename.txt');
    

    Here are some functions I put in my appController, so that any controller can output a CSV file if required:

        /**
     * Flattens the data that is returned from a find() operation, and puts it into CSV format
     * @param $data
     * @return string
     */
    public function _arrayToCsvFile($data){
        $flattenedData = array();
        $exportKeyPair = array();
        foreach($data as $datumKey => $datumDetails){
            $flattenedDatum = Hash::flatten($datumDetails, '.');
            $flattenedData[] = $flattenedDatum;
    
            // Find all keys
            if($datumKey == 0){
                $exportKeys = array_keys($flattenedDatum);
                $exportKeyPair = array_combine($exportKeys, $exportKeys);
            }
            else {
                $datumKeys = array_keys($flattenedDatum);
    
                $datumKeyPair = array_combine($datumKeys, $datumKeys);
    
                // Add the datum keys to the exportKeyPair if it's not already there
                $exportKeyPair = array_merge($exportKeyPair, $datumKeyPair);
            }
        }
    
        $exportKeyMap = array();
        foreach($exportKeyPair as $exportKey => $exportValue){
            $exportKeyMap[$exportKey] = "";
        }
    
    
        $outputCSV = '';
    
        $outputCSV .= $this->_arrayToCsvLine($exportKeyPair);
    
        foreach($flattenedData as $flattenedDatumKey => $flattenedDatumDetails){
    
            // Add any extra keys
            $normalisedDatumDetails = array_merge($exportKeyMap, $flattenedDatumDetails);
    
            $outputCSV .= $this->_arrayToCsvLine($normalisedDatumDetails);
        }
    
        return $outputCSV;
    }
    
        /**
     * arrayToCsvLine function - turns an array into a line of CSV data.
     *
     * @access public
     * @param mixed $inputLineArray the input array
     * @param string $separator (default: ")
     * @param string $quote (default: '"')
     * @return string
     */
    function _arrayToCsvLine($inputLineArray, $separator = ",", $quote = '"') {
        $outputLine = "";
    
        $numOutput = 0;
    
        foreach($inputLineArray as $inputLineKey => $inputLineValue) {
            if($numOutput > 0) {
                $outputLine .= $separator;
            }
    
            $outputLine .= $quote . str_replace(array('"', "\n", "\r"),array('""', "", ""), $inputLineValue) . $quote;
            $numOutput++;
        }
    
        $outputLine .=  "\n";
    
        return $outputLine;
    
    }
    
    /**
     * Serves some CSV contents out to the client
     * @param $csvContents
     * @param array $options
     */
    public function _serveCsv($csvContents, $options = array()){
    
        $defaults = array(
            'modelClass' => $this->modelClass,
            'fileName' => null
        );
    
        $settings = array_merge($defaults, $options);
    
        if(empty($settings['fileName'])){
            $settings['fileName'] = strtolower( Inflector::pluralize( $settings['modelClass'] ) ) . '_' . date('Y-m-d_H-i') . '.csv';
        }
    
        $this->autoRender = false;
    
        $this->response->type('Content-Type: text/csv');
        $this->response->download($settings['fileName']);
        $this->response->body($csvContents);
    }
    

    Now in any controller you can do this (note that you can pass the filename to _serveCsv if required):

    /**
     * admin_export_csv method
     *
     * @return void
     */
    public function admin_export_csv() {
        $this->Order->recursive = 0;
    
        $conditions = array();
    
        $orders = $this->Order->find('all', array('conditions' => $conditions));
    
    
        $csvContents = $this->_arrayToCsvFile($orders); // Function in AppController
    
        $this->_serveCsv($csvContents, array('filename' => 'export.txt')); // Function in AppController
    }