So, as the title implies, this is not general PHP approach, it is about how to do that in CodeIgniter.
Here is the solution found from the Internet: Excel CSV helper for CodeIgniter
But this snippet won't work for UTF-8 encoded characters. So I copied the code in the comment (posted by email@williamli.hk) discussing that issue:
if ($download != "")
{
/*
header('Content-Encoding: UTF-8');
header('Content-Type: text/csv; charset=UTF-8');
//header('Content-Type: application/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $download . '"');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
*/
header('Content-Description: File Transfer');
//header('Content-Type: application/octet-stream');
header("Content-Type: application/vnd.ms-excel; charset=UTF-16LE");
header('Content-Disposition: attachment; filename='.$download);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
//echo "\xEF\xBB\xBF"; // UTF-8 BOM
echo "\xFF\xFE"; // UTF-16 LE
}
My final code came to be:
if ( ! function_exists('array_to_csv'))
{
function array_to_csv($array, $download = "")
{
$CI =& get_instance();
if ($download != "")
{
header('Content-Encoding: UTF-8');
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $download . '"');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
}
ob_start();
$f = @fopen('php://output', 'w');
if (FALSE === $f)
{
$this->CI->app88log->log_message('csv', 'error', "Can't open php://output");
show_error($this->CI->lang->line('admin_export_excel_error_message'));
}
$n = 0;
foreach ($array as $line)
{
$n++;
try {
$res = fputcsv($f, $line);
if (FALSE === $res)
{
$this->CI->app88log->log_message('csv', 'error', 'Can not write line' . $n );
show_error($this->CI->lang->line('admin_export_excel_error_message'));
}
}
catch (Exception $e) {
$this->CI->app88log->log_message('csv', 'error', $e->getMessage());
show_error($this->CI->lang->line('admin_export_excel_error_message'));
}
}
fclose($f);
$str = ob_get_contents();
ob_end_clean();
if ($download == "")
{
return $str;
}
else
{
echo $str;
}
}
}
And it was saved under /application/helper/.
Then load it in controllers' constructor, and call it in method:
$fileName = 'product-' . gmdate('Y-m-d') . '.csv';
array_to_csv($csvData, $fileName);
exit;
Pass the two-dimension array of data to the function and let it take care of all the job left.