I am writing a plugin in which I need the user to be able to download a csv created on the fly (I don't want to use up server space). I have the text I need to print to csv pinted in a hidden element in a form, which I then echo and create csv using fopen and fclose. The problem is that new lines are not being parsed. I have tried adding slashes, closing the variable in double quotes, and output buffering. I have also set auto_detect_line_endings to true. Here is my code.
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$fp = fopen('php://output', 'w');
$data = $_POST['csv_holder'];
echo $data;
fclose($fp);
and the html:
<form id = 'wcds_$post_id_csv_download' action ='$download_file' method='post'><input type ='hidden' name = 'csv_holder' id ='wcds_download_csv_$post_id_value' value ='$wcds_item_details_string'><input type ='submit' id ='wcds_download_csv_$post_id' class ='wcds_download_button'</form>
example $wcds_item_details_string
: 1,2,3 4,5,6 7,8,9
$wcds_item_details_string = get_the_content();
//sanitise for html
$wcds_item_details_string = htmlspecialchars ( $wcds_item_details_string, ENT_QUOTES );
Tried string replace :
$replace = '\';
$backslash = '\\';
$wcds_item_details_string = str_replace( $backslash, $replace, $wcds_item_details_string );
Figured it out, the database was returning the variable as a single quoted string. I just had to use string replace to change the line breaks to double quoted. Final code:
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$fp = fopen('php://output', 'w');
$data = $_POST['csv_holder'];
$data= str_replace( '
', "
", $data );
echo "{$data}";
fclose($fp);
Hope it helps someone!
I'm posting this as the answer, as this was what solved my problem. The issue with fputs over echoing to the output buffer is a subject for another question.
The problem was the data was being output as a single quoted strings, so I had to replace the single quoted returns with double quoted ones.
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$fp = fopen('php://output', 'w');
$data = $_POST['csv_holder'];
$data= str_replace( '
', "
", $data );
echo "{$data}";
fclose($fp);
Hope it helps someone!
I have read comments under your question, but I really dont understand, why you open file, save reference to $fp
, and then echo $data
from your CSV, instead of using function fputs
:
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$fp = fopen('php://output', 'w');
$data = $_POST['csv_holder'];
$data= str_replace( '
', "
", $data );
echo "{$data}";
fclose($fp);
Try this:
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$fp = fopen('php://output', 'w');
$data = $_POST['csv_holder'];
$data= str_replace( '
', "
", $data );
fputs($fp, $data);
fclose($fp);
Or there is exactly option to store CSV data; you can use this function:
function outputCSV($data) {
$fp = fopen("php://output", 'w');
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals, ';', '"');
}
array_walk($data, '__outputCSV', $fp);
fclose($fp);
}