write utf-8 characters to file with fputcsv in php
Try this:
$df = fopen($filepath, 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($df, array($coupon->code, $discount->label));
the line fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
writes file header for correct encoding.
PHP fputcsv encoding
Default encoding for an excel file is machine specific ANSI, mainly windows1252
. But since you are creating that file and maybe inserting UTF-8 characters, that file is not going to be handled ok.
You could use iconv()
when creating the file. Eg:
function encodeCSV(&$value, $key){
$value = iconv('UTF-8', 'Windows-1252', $value);
}
array_walk($values, 'encodeCSV');
How can I output a UTF-8 CSV in PHP that Excel will read properly?
To quote a Microsoft support engineer,
Excel for Mac does not currently support UTF-8
Update, 2017: This is true of all versions of Microsoft Excel for Mac before Office 2016. Newer versions (from Office 365) do now support UTF-8.
In order to output UTF-8 content that Excel both on Windows and OS X will be able to successfully read, you will need to do two things:
Make sure that you convert your UTF-8 CSV text to UTF-16LE
mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
Make sure that you add the UTF-16LE byte order mark to the start of the file
chr(255) . chr(254)
The next problem that appears only with Excel on OS X (but not Windows) will be when viewing a CSV file with comma separated values, Excel will render rows only with one row and all of the text along with the commas in the first row.
The way to avoid this is to use tabs as your separated value.
I used this function from the PHP comments (using tabs "\t" instead of commas) and it worked perfectly on OS X and Windows Excel.
Note that to fix an issue with an empty column as the end of a row, that I did have to change the line of code that says:
$field_cnt = count($fields);
to
$field_cnt = count($fields)-1;
As some of the other comments on this page say, other spreadsheet apps like OpenOffice Calc, Apple's own Numbers and Google Doc's Spreadsheet have no issues with UTF-8 files with commas.
See the table in this question for what works and doesn't work for Unicode CSV files in Excel
As a side note, I might add that if you are using Composer, you should have a look at adding League\Csv
to your requires. League\Csv
has a really nice API for building CSV files.
To use League\Csv
with this method of creating CSV files, check out this example
Adding BOM to CSV file using fputcsv
Thanks to Mark Baker for this answer:
I needed to use fwrite() to add the BOM, not fputcsv().
The working version looks like this:
if(file_exists($file)) {
$fp = fopen($file, 'a');
if($fp &&
fputcsv($fp, $submittedForm) &&
fclose($fp)) {
return true;
}
} else {
$fp = fopen($file, 'w');
fwrite($fp, $BOM); // NEW LINE
if($fp &&
fputcsv($fp, $fields) &&
fputcsv($fp, $submittedForm) &&
fclose($fp)) {
return true;
}
}
Thanks, Mark!
PHP fputcsv does not display Chinese Character Correctly
In your case the problem was not in PHP. When you open a csv file in Excel it shows you a window, where you can setup CSV importing options like delimiter and encoding. You should choose UTF-8
encoding to view those Chinese characters.
Related Topics
Yii2 Global Filter/Behavior to Force User to Authenticate First
Utf8 Filenames in PHP and Different Unicode Encodings
How to Install Laravel Without Using Composer
PHP Regex to Remove Http:// from String
Is There a Function to Make a Copy of a PHP Array to Another
Extract Url's from a String Using PHP
How to Write to the Console from a Laravel Controller
Check If a PHP Cookie Exists and If Not Set Its Value
Changing the Add to Cart Button Text in Woocommerce for Items with Variations
Read Associative Array from JSON in $_Post
How to Only Use Created_At in Laravel
Cannot Call Function SQLsrv_Connect()
Wordwrap/Cut Text in HTML String
Jquery Tablesorter Index Column Insert
How to Trigger Xdebug Profiler for a Command Line PHP Script