This question already has answers here:
Is it possible to force Excel recognize UTF-8 CSV files automatically?
(30 answers)
Microsoft Excel mangles Diacritics in .csv files?
(22 answers)
Closed 4 years ago.
There might be similar question, but I am sorry to say that I couldn't find that. So let me ask about my problem.
I have a PHP function to download CSV file from browser as below:
function outputCSV($data, $file_name = 'file.csv') {
header('Content-Encoding: UTF-8');
# output headers so that the file is downloaded rather than displayed
header('Content-type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=$file_name");
header('Content-Transfer-Encoding: binary');
# Disable caching - HTTP 1.1
header("Cache-Control: no-cache, no-store, must-revalidate");
# Disable caching - HTTP 1.0
header("Pragma: no-cache");
# Disable caching - Proxies
header("Expires: 0");
# Start the ouput
$output = fopen("php://output", "w");
fputs($output, "\xEF\xBB\xBF"); // UTF-8 BOM !!!!!
# Then loop through the rows
foreach ($data as $row) {
# Add the rows to the body
fputcsv($output, $row); // here you can change delimiter/enclosure
}
# Close the stream off
fclose($output);
}
After downloading the file, while open using Windows 10 Excel app the Japanese characters are wired. But can be viewed properly using Text Editor like NotePad++.
Is there any help on this?
Thanks.
Related
This question already has answers here:
PHP output file on disk to browser
(6 answers)
PHP: How to make browser to download file on click
(2 answers)
Closed 5 years ago.
I have PHP files stored on my server, and their names in the mysql database, I want to download those files. What code should I write for the same? I am using PHP as coding language. Please help.
<?php
$file = 'send_me.pdf';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
Obviously, set $file to the file name.
Read more about the use of readfile here.
Download?
Literally just make a link the stored file.
file_put_contents("PDFName.pdf", fopen("http://someurl/PDFName.pdf", 'r'));
You really should show what you have done so far/researched online before asking a question!
This will download the file PDFName.pdf from the url http://someurl/PDFName.pdf and put it into the same directory as the script is in.
I create a CSV file using fputcsv in PHP. File is created successfully and I can open the file in MacOS with no problem. (I use Numbers in MacOS). The problem is in Microsoft Excel, it shows all row as merged one single column.
I set delimiter as ";" in the code.
When I check for Language and Regional Settings as told in Microsoft documentation, the delimiter is also ";".
What should I also check for?
Thank you.
Well this header will allow the csv format to displayed properly.
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename=filename.csv');
echo "\xEF\xBB\xBF";
You can use this header
The following method seems to do the trick for me. Microsoft Excel opens it perfectly.
$filePath = '/home/user/';
$filename = 'test.csv';
$df = fopen($filePath.$filename, 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($df, $dataColumns);
foreach ($dataArray as $dataRow) {
fputcsv($df, $dataRow);
}
fclose($df);
// Output csv
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$filename);
header("Cache-Control: no-store, no-cache");
readfile($filePath.$filename);
Notes
the line fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF)); writes file header for correct encoding.
You can use the third parameter of fputcsv(...) to set the delimiter.
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 7 years ago.
I read a whole bunch of articles in SO and the internet and tried all of them but I am still unable to create a CSV download functionality in PHP.
Following is my code:
$csvData = #$_POST['csv_data'];
if(trim($csvData))
{
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=data.csv");
header("Expires: 0");
header("Pragma: public");
echo $csvData;
exit;
}
Instead of showing the file save dialog, this keeps printing the CSV data into my browser :( What am I doing wrong here? Any help is much appreciated..
Additional Edit: I am posting this data into my script, which immediately takes this data and tries to download. My script is an include inside another file, will that be a problem? I enabled error_reporting and found that I am getting header already modified error...
In HTTP, headers are sent before any text output.
For that reason, PHP will close your response header if you output any text.
Make sure that you hold any text output before your header modification, for example using the OB-cache.
i have a tar archive on the server that must be downloadable through php. This is the code that i've used:
$content=file_get_contents($tar);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=$tar");
header("Content-Length: ".strlen($content));
unlink($name);
die($content);
The file is downloaded but it's broken and it can't be open. I think that there's something wrong with headers because the file on the server can be open without problems. Do you know how can i solve this problem?
UPDATE
I've tried to print an iframe like this:
<iframe src="<?php echo $tar?>"></iframe>
And the download works, so i'm sure that there's something missing in headers.
I have used this code when I have had to do it:
function _Download($f_location, $f_name){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($f_location));
header('Content-Disposition: attachment; filename=' . basename($f_name));
readfile($f_location);
}
_Download("../directory/to/tar/raj.tar", "raj.tar");
//or
_Download("/var/www/vhost/domain.com/httpdocs/directory/to/tar/raj.tar", "raj.tar");
Try that.
Don't use file_get_contents() and then echo or print to output the file. That loads the full contents of the file into memory. A large file can/will exceed your script's memory_limit and kill the script.
For dumping a file's contents to the client, it's best to use readfile() - it will properly slurp up file chunks and spit them out at the client without exceeding available memory. Just remember to turn off output buffering before you do so, otherwise you're essentially just doing file_get_contents() again
So, you end up with this:
$tar = 'somefile.tar';
$tar_path = '/the/full/path/to/where/the/file/is' . $tar;
$size = filesize($tar_path);
header("Content-Type: application/x-tar");
header("Content-Disposition: attachment; filename='".$tar."'");
header("Content-Length: $size");
header("Content-Transfer-Encoding: binary");
readfile($tar_path);
If your tar file is actually gzipped, then use "application/x-gtar" instead.
If the file still comes out corrupted after download, do some checking on the client side:
Is the downloaded file 0 bytes, but the download process seemed to take much longer than it would take for 0 bytes to transfer, then it's something client-side preventing the download. Virus scanner? Trojan?
Is the downloaded file partially present, but smaller than the original? Something killed the transfer prematurely. Overeager firewall? Download manager having a bad day? Output buffering active on the server and the last buffer bucket not being flushed properly?
Is the downloaded file the same size as the original? Do an md5/sha1/crc checksum on both copies. If those are the same, then something's wrong with the app opening the file, not the file itself
Is the downloaded file bigger than the original? Open the file in notepad (or something better like notepad++ which doesn't take years to open big fils) and see if any PHP warnings messages, or some invisible whitespace you can't see in your script got inserted into the download at the start or end of the file.
Try something like the following:
$s_filePath = 'somefile.ext';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'. s_filePath.'"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header("Content-Length: ".filesize($s_filePath));
$r_fh = fopen($s_filePath,'r');
while(feof($r_fh) === false) {
$s_part = fread($r_fh,10240);
echo $s_part;
}
fclose($r_fh);
exit();
Use Content-Type: application/octet-stream or Content-Type: application/x-gtar
Make sure you aren't echoing anything that isn't the file output. Call ob_clean() before the headers
This question already has answers here:
php - How to force download of a file?
(7 answers)
Closed 7 years ago.
I have a php page with information, and links to files, such as pdf files. The file types can be anything, as they can be uploaded by a user.
I would like to know how to force a download for any type of file, without forcing a download of links to other pages linked from the site. I know it's possible to do this with headers, but I don't want to break the rest of my site.
All the links to other pages are done via Javascript, and the actual link is to #, so maybe this would be OK?
Should I just set
header('Content-Disposition: attachment;)
for the entire page?
You need to send these two header fields for the particular resources:
Content-Type: application/octet-stream
Content-Disposition: attachment
The Content-Disposition can additionally have a filename parameter.
You can do this either by using a PHP script that sends the files:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment');
readfile($fileToSend);
exit;
And the filenames are passed to that script via URL. Or you use some web server features such as mod_rewrite to force the type:
RewriteEngine on
RewriteRule ^download/ - [L,T=application/octet-stream]
Slightly different style and ready to go :)
$file = 'folder/' . $name;
if (! file) {
die('file not found'); //Or do something
} else {
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile($file);
}