1

UPDATE: I have changed the code in order to insert a BOM, with no possitive result. Here's the updated piece of code:

$output = fopen($file, 'w'); $utf8_output_with_bom = chr(239) . chr(187) . chr(191) . $output; fputcsv($output, array('NOMBRE','APELLIDO','TELEFONO', 'RESPUESTA', 'DIA', 'HORA'), "\t"); if ($key1!="No definida"){ // fetch the data $rows1 = mysqli_query($con, "SELECT cm_name, cm_surname, cr_phone, cr_message, DATE_FORMAT(cr_time,'%d/%m/%Y'), DATE_FORMAT(cr_time,'%H:%i') FROM ws_campreplies JOIN ws_campmsg WHERE cr_phone=cm_phone AND cr_fk_us_id='$id' AND cr_message='$key1' AND cm_fk_ca_id='$ca_id'"); // loop over the rows, outputting them while ($row1 = mysqli_fetch_assoc($rows1)) { fputcsv($output, $row1, "\t"); } } 

I have a utf8_general_ci database, with this example of records on the two involved tables (all utf8_general_ci):

Table ws_campmsg:

ws_campmsg

Table ws_campreplies:

ws_campreplies

The only thing I need is to export this on Excel, and this is almost done. This PHP file creates a SQL and exports a correct XLS file:

$con = mysqli_connect(DB_SERVER,DB_USER,DB_PASS,DB_NAME); mysqli_set_charset($con, 'utf8'); [....] $ca_id = $_POST['ca_id']; $key1 = $_POST['key1']; $file='../uploads/TemporalCsv_'.time().'.xls'; header("Content-Type: application/xls"); header("Content-Disposition: attachment; filename=$file"); header("Pragma: no-cache"); header("Expires: 0"); $output = fopen($file, 'w'); fputcsv($output, array('NOMBRE','APELLIDO','TELEFONO', 'RESPUESTA', 'DIA', 'HORA'), "\t"); if ($key1!="No definida"){ // fetch the data $rows1 = mysqli_query($con, "SELECT cm_name, cm_surname, cr_phone, cr_message, DATE_FORMAT(cr_time,'%d/%m/%Y'), DATE_FORMAT(cr_time,'%H:%i') FROM ws_campreplies JOIN ws_campmsg WHERE cr_phone=cm_phone AND cr_fk_us_id='$id' AND cr_message='$key1' AND cm_fk_ca_id='$ca_id'"); // loop over the rows, outputting them while ($row1 = mysqli_fetch_assoc($rows1)) { fputcsv($output, $row1, "\t"); } } fclose($output); echo $file; 

If I pass ca_id="438", and key1="CLAVE7", the exported file is right this one:

xls


As you see the only problem now is that it does not show properly accents like á or Á. As I have searched quite a bit about solving this, there are some tries I have made with no possitive result, like trying to export on text format dfirectly on browser (exports the same coding mistakes):

$file='../uploads/TemporalCsv_'.time().'.txt'; header("Content-Type: text/tab-separated-values"); 

Also tried changing headers (exports the same coding mistakes)

header("Content-Type: application/vnd.ms-excel; charset=utf-8"); header("Content-type: application/x-msexcel; charset=utf-8"); header("Content-Disposition: attachment; filename=ventas.xls"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); 

On the last tries I found that maybe converting with iconv() would be effective, but with this modification an error emerges, as html_entity_decode() accepts strings, not arrays:

if ($key1!="No definida"){ // fetch the data $rows1 = mysqli_query($con, "SELECT cm_name, cm_surname, cr_phone, cr_message, DATE_FORMAT(cr_time,'%d/%m/%Y'), DATE_FORMAT(cr_time,'%H:%i') FROM ws_campreplies JOIN ws_campmsg WHERE cr_phone=cm_phone AND cr_fk_us_id='$id' AND cr_message='$key1' AND cm_fk_ca_id='$ca_id'"); // loop over the rows, outputting them while ($row1 = mysqli_fetch_assoc($rows1)) { iconv("UTF-8","WINDOWS-1255",html_entity_decode( $row1 ,ENT_COMPAT,'utf-8')); fputcsv($output, $row1, "\t"); } } 

I hope I explained myself crearly. The use of PHPExcel is my last chance, if there is any posibility of correcting this issue without using PHPExcel, I would prefer it. Very grateful.

6
  • 1
    Don't open it directly in Excel ... instead create a new spreadsheet and then do data > import from file ... when you do that you can specify the character encoding of the data import to use utf-8 rather than Windows-1252
    – CD001
    CommentedJun 25, 2015 at 10:18
  • Thank you. But is it not an spreadsheet what I am creating? I am confused about differences on opening in Excel and creating an sporeadsheet, is it not the same? The spreadsheet itself gets created under the $file directory, you mean taking that and doing a data > import from file...?CommentedJun 25, 2015 at 10:22
  • 1
    Basically once you've exported the .xls file don't double-click on it to open it in Excel. Instead open Excel and use the data > import from file tool to import the data into your spreadsheet. That import tool allows you to specify the character set that the data is in. If you double-click to open the .xls file, Excel assumes the character encoding will be Windows-1252 and scrambles your data.
    – CD001
    CommentedJun 25, 2015 at 10:27
  • I understand now. The problem is that this is an AJAX aplication, and whats is being echoed (the $file value, that means the final directory and file) gets automatically opened on a new tab, so it is not manually opened by the final user. Optimal solution would be to pass a final directory and file with that file itself previously encoded. Is there any way of making this trough PHP instead of trough Excel?CommentedJun 25, 2015 at 10:31
  • 1
    It's more an Excel problem than a PHP problem... I run into it every time I do a data dump from PHPMyAdmin. Your best bet is probably to throw it at Google Spreadsheet instead according to this answer : stackoverflow.com/questions/4221176/…
    – CD001
    CommentedJun 25, 2015 at 10:33

1 Answer 1

3

You have to add a BOM at the beginning of your output.

$utf8_output_with_bom = chr(239) . chr(187) . chr(191) . $utf8_output; 

The BOM is not required in UTF8.

Example:

$output = fopen($file, 'w'); fwrite($output, chr(239) . chr(187) . chr(191)); // Write the BOM to the beginning of the file fputcsv($output, <...>); fclose($output); 

Code to write the CSV:

$output = fopen($file, 'w'); fwrite($output, chr(239) . chr(187) . chr(191)); fputcsv($output, array('NOMBRE', 'APELLIDO', 'TELEFONO', 'RESPUESTA', 'DIA', 'HORA'), "\t"); if ($key1 != "No definida") { // fetch the data $rows1 = mysqli_query($con, "SELECT cm_name, cm_surname, cr_phone, cr_message, DATE_FORMAT(cr_time,'%d/%m/%Y'), DATE_FORMAT(cr_time,'%H:%i') FROM ws_campreplies JOIN ws_campmsg WHERE cr_phone=cm_phone AND cr_fk_us_id='$id' AND cr_message='$key1' AND cm_fk_ca_id='$ca_id'"); // loop over the rows, outputting them while ($row1 = mysqli_fetch_assoc($rows1)) { fputcsv($output, $row1, "\t"); } } fclose($output); 
3
  • So after creating the file with $output = fopen($file, 'w'); I must set the next line as $utf8_output_with_bom = chr(239) . chr(187) . chr(191) . $output; ?CommentedJun 25, 2015 at 13:16
  • I have updated the top of the cuestion with the edition I made on the code to add the BOM. Please check. I guess I do not know how to structurate this addition on the EXCEL file...CommentedJun 25, 2015 at 13:22
  • Could not continue with this untill today. Your help has make this work, thank you,CommentedJul 6, 2015 at 4:55

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.