Create CSV and Force to Download - php

I want write a CSV and force to Download it automatically. Bit it only displays the file. My code:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
// open to write
$fp = fopen($fileName, 'w');
// MS-Excel BOM:
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
// write columns
foreach ($columnNames as $fields) {
fputcsv($fp, $fields, ';');
}
$exportData = array (
array($value1, $value2, $value3)
);
foreach ($exportData as $fields) {
fputcsv($fp, $fields, ';');
}
fclose($fp);
I have tried for hours. Nothing do the job. It will only be displayd.

You can try adding the file to a zip file and asking your visitors to change their settings so that zip files are automatically downloaded.
https://www.tipsandtricks-hq.com/forum/topic/force-a-file-to-download-instead-of-showing-up-in-the-browser

Related

How do I know how many times my file has really downloaded?

The task is to create a controller to count the number of file downloads. It also must be able to account for failed or cancelled downloads. I was wondering if anyone knew the best way to go about accomplishing this.
$file = $_GET['download'];
if (ob_get_level()) {
ob_end_clean();
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
return filesize($file);`
$size = filesize($file);
Then if the number of bytes given is approximately equal to the file size:
if ( $size < given bytes) {
$handle = fopen("counter.txt", "r");
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$buffer=$buffer+1;
}
fclose($handle);
$fp = fopen("counter.txt", "w");
$test = fwrite( $fp, $buffer);
fclose($fp);
}
How to know the number of bytes sent by server to the user after clicking on link?
I'll start with what should be comments:
You've tagged this as javascript, but your quesiotn appears to have nothing to do with javascript. Please don't do that.
I assume you are aware of the gaping security hole exposed by your script / that you are not concerned about it.
Your handling of output buffering is wrong.
return filesize($file);
What is this line of code supposed to do?
header('Expires: 0');
no.
header('Pragma: public');
again, no.
As to your question - its all covered in the manual:
<?php
ignore_user_abort(1);
$file = $_GET['download'];
if (!is_readable($file)) {
die "No such file";
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0; must-revalidate');
header('Content-Length: ' . filesize($file));
$count=0;
$ih=fopen($file, 'r');
while (CONNECTION_NORMAL==connection_status() && !feof($ih)) {
print fgets($ih, 4096);
}
log_completion(feof($ih));
BTW: This does not give an accurate record if the file was downloaded - you can only tell if the content has left PHP land.

Issues with exporting a csv file

I'm creating a function that, when you click on a button, submits datas to a this function and in return, creates a .csv file and makes the browser download it. I followed the huge amount of tutorials that can be found online, but maybe I'm mixing up things:
header("Content-Type: application/x-excel");
header("Content-disposition: attachment; filename=export".date('d-m-Y') .".csv");
header('Expires : 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
$list = array
(
"Peter,Griffin,Oslo,Norway",
"Glenn,Quagmire,Oslo,Norway",
);
$file = fopen("contacts.csv","w");
foreach ($list as $line) {
fputcsv($file,explode(',',$line));
}
die($file);
readfile($file);
Just keep in mind that these aren't my real datas, I just want to set everything up before continuing, because I have 50 lines of an array to handle.
With this code, If I keep die($file), the file gets downloaded but is empty. If I remove it, my browser tells me that the website is unavailable.
What am I missing?
try this
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$data = array(
"Peter,Griffin,Oslo,Norway",
"Glenn,Quagmire,Oslo,Norway",
);
$fp = fopen('php://output', 'w');
foreach ( $data as $line ) {
$val = explode(",", $line);
fputcsv($fp, $val);
}
fclose($fp);

Outputting and saving a csv in PHP

I am currently creating and outputting a CSV as follows:
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file.csv');
header("Cache-Control: no-store, no-cache");
$df = fopen('php://output', 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($df, $csvLine);
}
exit;
However, I would like to not only output but also save this file to disk. How can I write $df to a file?
Note Suggestions on improving my generating the CSV are welcome :)
The simplest answer is to write to the file instead of php://output, and then send that file directly to the browser using readfile()
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file.csv');
header("Cache-Control: no-store, no-cache");
$df = fopen('/path/to/where/you/want/the/file/on/disk.csv', 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($df, $csvLine);
}
readfile('/path/to/where/you/want/the/file/on/disk.csv');
exit;
Simply write to two file pointers:
$out = fopen('php://output', 'w');
$file = fopen('somefile.csv');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($out, $csvLine);
fputcsv($file, $csvLine);
}
exit;

How to stop foreach loop from printing duplicate data?

I am trying to generate unique CSV files from the csv data that I have using the following loop.
$k =1;
foreach ($csv_tbl as $_csv) {
$filename = "Agent_" . $k . ".csv";
$file_path = "agents/$filename";
file_put_contents($file_path, $_csv);
if (file_exists($_csv)) {
header('Content-Description: File Transfer');
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename=' . $filename);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($_csv));
readfile($_csv);
die();
}
$k++;
}
The first file generated is perfect and only has the data it should have i.e the first csv table. The second file has both the first and the second tables this goes on for all my 21 files which means the 21st file will have all the tables.
Visual example of the first two files.
How can I prevent duplicates tables from my csv file?
As your foreach is printing duplicates , it means that your array $csv_tbl contains duplicate values, you can remove duplicate values from array using array_unqiue But also by looking at the screenshots i can see that the callid is different for every record. do your csv contain duplicates?::
$k =1;
$csv_tbl = array_unique($csv_tbl);
foreach ($csv_tbl as $_csv) {
$filename = "Agent_" . $k . ".csv";
$file_path = "agents/$filename";
file_put_contents($file_path, $_csv);
if (file_exists($_csv)) {
header('Content-Description: File Transfer');
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename=' . $filename);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($_csv));
readfile($_csv);
die();
}
$k++;
}

Non-ascii characters in fputcsv

So I have a simple script that writes some data to a CSV-file. The file contains a few non-ascii characters (norwegian characters) which are not displayed correctly in when opened in Excel. However they are displayed correctly in OpenOffice. Does anyone know how to fix this?
$fp = fopen('php://output', 'w');
if(!$fp)
{
echo "Could not write CSV-file"; die;
}
$filename = sprintf('%s_export_%s.csv', $marketplace, date('Y_m_d_H_i_s'));
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Pragma: no-cache');
header('Expires: 0');
foreach($collection as $i => $item)
{
$result = array();
$result[] = $item->getData('email');
$result[] = $item->getData('firstname');
$result[] = $item->getData('lastname');
fputcsv($fp,$result, ";");
}
flush();
fclose($fp);
Windows needs a BOM to know that a file is UTF-8 and open it correctly.
Before your foreach, add the following line:
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));

Categories