<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GTD Tools - AllMyThingsTodo &#187; csv</title>
	<atom:link href="http://blog.allmythingstodo.com/tag/csv/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.allmythingstodo.com</link>
	<description>Personal Productivity Blog, tasks management and tips</description>
	<lastBuildDate>Sun, 05 Sep 2010 09:18:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Adding a CSV Export Feature</title>
		<link>http://blog.allmythingstodo.com/adding-a-csv-export-feature/</link>
		<comments>http://blog.allmythingstodo.com/adding-a-csv-export-feature/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 11:32:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[export]]></category>

		<guid isPermaLink="false">http://blog.allmythingstodo.com/adding-a-csv-export-feature/</guid>
		<description><![CDATA[Hi All: This is a mini-howto to add a simple &#8220;export to csv&#8221; feature, so you can control your tasks and projects inside excel, or build reports of what you&#8217;ve done for a group of projects. All the filters apply before the CSV file is created. Note: The link to build the CSV is located [...]]]></description>
			<content:encoded><![CDATA[<p>Hi All:</p>
<p>This is a mini-howto to add a simple &#8220;export to csv&#8221; feature, so you can control your tasks and projects inside excel, or build reports of what you&#8217;ve done for a group of projects.</p>
<p>All the filters apply before the CSV file is created.</p>
<p>Note: The link to build the CSV is located at the bottom of the Tasks table.</p>
<p>Step by step tutorial:</p>
<ul>
<li>Download this <a href="http://ifunk.net/cakephp/helpers/csv.php.txt">helper code</a>. Note: the original code was posted by Adam Royle <a href="http://groups.google.es/group/cake-php/browse_thread/thread/4e2e5aad49c23b40">here</a> i&#8217;m just copying his code for PHP 4 &amp; 5:</li>
</ul>
<pre>&lt;?php/*** CSV helper for cakePHP. Compatible with version 1.1.x.x and higher.*

* PHP versions 4 and 5

*

* Licensed under The MIT License

*

* @copyright		Adam Royle

* @license			http://www.opensource.org/licenses/mit-license.php The MIT License

*/

class CsvHelper extends Helper {	var $delimiter = ',';

var $enclosure = '"';

var $filename = null;

var $line = array();

var $buffer;

/**

* This option preserves leading zeros on numeric data when opened in Excel.

* Use it ONLY when the csv file is going to be opened in Excel, as it uses

* non-standard syntax, and will probably break in other systems.

*/

var $preserveLeadingZerosInExcel = false;

var $_tmpFile = false;

function CsvHelper() {

$this-&gt;clear();

}

/**

* Adds a multi-dimensional array to the buffer.

*

* @param array $data Multi-dimensional array

* @param boolean $addFieldNames Add a row of field names before adding data

* @access public

*/

function addGrid($data, $addFieldNames = true, $fieldList = null) {

if (!$data) {

return false;

}

if (@is_array(reset($row = reset($data)))) {

// Array generated by cakePHP model

// eg.

// $data = array(array('Model' =&gt; array('field_name' =&gt; 'field value')), array('Model' =&gt; array('field_name' =&gt; 'field value')))

$defaultModel = key($row);

if ($this-&gt;filename === null) {

$this-&gt;setFilename(Inflector::pluralize($defaultModel));

}

if ($fieldList) {

$fields = array();

foreach ($fieldList as $fieldName) {

if (strpos($fieldName, '.')) {

list($modelName, $fieldName) = explode('.', $fieldName);

} else {

$modelName = $defaultModel;

}

$fields[] = array(Inflector::humanize($modelName), $fieldName);

}

if ($addFieldNames){

foreach ($fields as $field) {

if ($field[0] != $defaultModel) {

$this-&gt;addField($field[0].' '.Inflector::humanize($field[1]));

} else {

$this-&gt;addField(Inflector::humanize($field[1]));

}

}

$this-&gt;endRow();

}

foreach ($data as $row) {

foreach ($fields as $field) {

@$this-&gt;addField($row[$field[0]][$field[1]]);

}

$this-&gt;endRow();

}

} else {

if ($addFieldNames){

foreach (reset($row) as $key =&gt; $value) {

$this-&gt;addField(Inflector::humanize($key));

}

$this-&gt;endRow();

}

foreach ($data as $row) {

$this-&gt;addRow($row[$defaultModel]);

}

}

} else {

// Regular 2-dimensional array (with or without keys).

// eg.

//			$data = array(array('field_name' =&gt; 'field_value'), array('field_name' =&gt; 'field_value'))

//	or

//			$data = array(array('field value'), array('field value'))

if ($fieldList) {

if ($addFieldNames){

foreach ($fieldList as $fieldName) {

$this-&gt;addField(Inflector::humanize($fieldName));

}

$this-&gt;endRow();

}

foreach ($data as $row) {

foreach ($fieldList as $fieldName) {

@$this-&gt;addField($row[$fieldName]);

}

$this-&gt;endRow();

}

} else {

if ($addFieldNames) {

foreach (reset($data) as $key =&gt; $value) {

$this-&gt;addField(Inflector::humanize($key));

}

$this-&gt;endRow();

}

foreach ($data as $row) {

$this-&gt;addRow($row);

}

}

}

}

/**

* Adds a single field value to the buffer. You must call $csv-&gt;endRow() to commit fields to the buffer.

*

* @param string $value Field value

* @access public

*/

function addField($value) {

$this-&gt;line[] = $value;

}

/**

* Commits the row of fields that were added by addField()

*

* @access public

*/

function endRow() {

$this-&gt;addRow($this-&gt;line);

$this-&gt;line = array();

}

/**

* Adds a single row to the buffer.

*

* @param array $row Data to be added

* @access public

*/

function addRow($row) {

if ($this-&gt;preserveLeadingZerosInExcel) {

// convert the number to a string formula

foreach ($row as $key =&gt; $value){

if (strlen($value) &gt; 1 &amp;&amp; $value[0] == '0' &amp;&amp; is_numeric($value)) {

$row[$key] = '="'.$value.'"';

}

}

}

fputcsv($this-&gt;buffer, $row, $this-&gt;delimiter, $this-&gt;enclosure);

}

/**

* Outputs headers

*

* @param string $filename Filename to save as

* @access public

*/

function renderHeaders($filename = null) {

if (is_string($filename)) {

$this-&gt;setFilename($filename);

}

if ($this-&gt;filename === null) {

$this-&gt;filename = 'Data.csv';

}

if ($this-&gt;filename) {

header("Content-disposition:attachment;filename=".$this-&gt;filename);

}

header("Content-type:application/vnd.ms-excel");

}

/**

* Sets the output filename. Automatically appends .csv if necessary.

*

* @param string $filename Filename to save as

* @access public

*/

function setFilename($filename) {

$this-&gt;filename = $filename;

if (strtolower(substr($this-&gt;filename, -4)) != '.csv') {

$this-&gt;filename .= '.csv';

}

}

/**

* Returns CSV string and clears internal buffer. Outputs headers() if necessary.

*

* @param mixed $outputHeaders Boolean to determine if should output headers, or a string to set the filename

* @param string $to_encoding Encoding to use

* @param string $from_encoding

* @return string String CSV formatted string

* @access public

*/

function render($outputHeaders = true, $to_encoding = null, $from_encoding = "auto") {

if ($outputHeaders) {

if (is_string($outputHeaders)) {

$this-&gt;setFilename($outputHeaders);

}

$this-&gt;renderHeaders();

}

if ($this-&gt;_tmpFile) {

rewind($this-&gt;buffer);

$output = '';

while (!feof($this-&gt;buffer)) {

$output .= fread($this-&gt;buffer, 8192);

}

fclose($this-&gt;buffer);

} else {

rewind($this-&gt;buffer);

$output = stream_get_contents($this-&gt;buffer);

}

// get around excel bug (http://support.microsoft.com/kb/323626/)

if (substr($output,0,2) == 'ID') {

$pos = strpos($output, $this-&gt;delimiter);

if ($pos === false) {

$pos = strpos($output, "\n");

}

if ($pos !== false) {

$output = $this-&gt;enclosure . substr($output, 0, $pos) . $this-&gt;enclosure . substr($output, $pos);

}

}

if ($to_encoding) {

$output = mb_convert_encoding($output, $to_encoding, $from_encoding);

}

$this-&gt;clear();

return $this-&gt;output($output);

}

/**

* Clears internal buffer. This is called automatically by CsvHelper::render()

*

* @access public

*/

function clear() {

$this-&gt;line = array();

$this-&gt;buffer = @fopen('php://temp/maxmemory:'.(5*1024*1024), 'r+');

if ($this-&gt;buffer === false) {

$this-&gt;_tmpFile = true;

$this-&gt;buffer = tmpfile();

}

}

}

/**

* A PHP4 implementation of the equivalent PHP5 function

*

* See (http://www.php.net/manual/en/function.fputcsv.php) for details

*/

if (!function_exists('fputcsv')) {

function fputcsv(&amp;$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {

$str = '';

$escape_char = '\\';

foreach ($fields as $value) {

settype($value, 'string');

if (strpos($value, $delimiter) !== false ||

strpos($value, $enclosure) !== false ||

strpos($value, "\n") !== false ||

strpos($value, "\r") !== false ||

strpos($value, "\t") !== false ||

strpos($value, ' ') !== false) {

$str2 = $enclosure;

$escaped = 0;

$len = strlen($value);

for ($i=0;$i&lt;$len;$i++) {

if ($value[$i] == $escape_char) {

$escaped = 1;

} else if (!$escaped &amp;&amp; $value[$i] == $enclosure) {

$str2 .= $enclosure;

} else {

$escaped = 0;

}

$str2 .= $value[$i];

}

$str2 .= $enclosure;

$str .= $str2.$delimiter;

} else {

$str .= $value.$delimiter;

}

}

$str = substr($str,0,-1);

$str .= "\n";

return fwrite($handle, $str);

}

}

?&gt;</pre>
<ul>
<li>Copy this code into file /app/views/helpers/csv.php</li>
<li>Add the helper to the controller where you are planning to use the CSV export feature.</li>
</ul>
<p><code>class XXXController extends AppController {<br />
</code><code>.....<br />
</code><code>    var $helpers = array('Html', 'Form' , 'Javascript', 'Ajax', <strong>'Csv'</strong>);</code><br />
<code>.....</code></p>
<ul>
<li>Create an export method that fetches the data (with a findAll for example) and set the data to the view. This method goes inside the controller with the CSV helper, of course <img src='http://blog.allmythingstodo.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p><code>  function exportcsv() {<br />
$this-&gt;layout = '';<br />
$this-&gt;set('dataToExport', $this-&gt;ZZZZ-&gt;findAll());</code></p>
<p><code>  }</code></p>
<ul>
<li>Now, create a file in /app/views/yourcontrollername/exportcsv.ctp with this contents</li>
</ul>
<p><code>&lt;?php<br />
$csv-&gt;addGrid($</code><code>dataToExport</code><code>);<br />
echo $csv-&gt;render(true);<br />
?&gt;</code></p>
<ul>
<li>Done !</li>
</ul>
<p>Notes: If you want to test the code generated, change render(false) for render(true) on the view, and the code will be shown on the browser.</p>
<p>Enjoy this new feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.allmythingstodo.com/adding-a-csv-export-feature/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
