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!
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
}