Export data from MySQL to Excel with UTF-8 encoding

30,843

Solution 1

You are generating CSV, which is basically a plain text file. There's no way to specify encoding information in such kind of files. Most text editors implement (better or worse) encoding auto-detection. Excel doesn't. Excel will simply assume ANSI when you right-click on a CSV file. (You need to use the "Open" menu in order to be prompted about encoding.)

Your only option left (apart from switching to another output format) is converting data to ANSI, either with mb_convert_encoding() or with iconv(). But now you have another problem: ANSI is not a real encoding, it basically means "whatever encoding is set in my Windows computer". You first have to find out the typical encoding most of your users have. That mostly depends on the country. For instance, many Western Europe countries use Win-1252.

Solution 2

I had the same problem (common problem in databases with spanish language). I wrote this and it worked:

This is a Class that connects with the database and the functions will do whatever you want using mysqli and PHP. In this case, calling this class (require or include), just use the "downloadCsv()" function.

As an example, this would be the "class.php" file:

<?php
class DB{

private $con;

//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");

if($this->con->connect_errno > 0){
    die('There was a problem [' . $con->connect_error . ']');
    }
}

//create the function that will download a csv file from a mysqli query

public function downloadCsv(){

$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
    $header .= $value->name.";";
    }
}
//put rows from your query
while($row = $result->fetch_row())  {
    $line = '';
    foreach($row as $value)       {
        if(!isset($value) || $value == "")  {
            $value = ";"; //in this case, ";" separates columns
    } else {
            $value = str_replace('"', '""', $value);
            $value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
        }
        $line .= $value;
    } //end foreach
    $data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
    $data = "\nno matching records found\n";
}
$count = $result->field_count;

//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";

}
?>

After creating the "class.php" file, in this example, use that function on "download.php" file:

<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>

After download, open the file with MS Excel.

I hope this help you, I think I wrote it well, I didn't feel comfortable with the text and code field.

Share:
30,843
bukowski
Author by

bukowski

Updated on February 01, 2020

Comments

  • bukowski
    bukowski over 4 years

    I have a mysql row with utf8_general_ci collation, when I export it to csv, instead of correct utf-8 characters I get Ć…ā€¦I etc, how to make excel understand UTF-8 encoding here is my code:

    $conn = mysql_connect('localhost', 'root', 'asdfggh') or die(mysql_error());
    mysql_query("SET CHARACTER SET utf8"); 
    mysql_query("SET NAMES utf8"); 
    mysql_select_db('table_name', $conn) or die(mysql_error($conn));
    
    $query = sprintf('SELECT * FROM sudraba_birzs');
    $result = mysql_query($query, $conn) or die(mysql_error($conn));
    
    header('Content-Encoding: UTF-8');
    header('Content-type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="'.date("d-m-Y_H:i") . '.csv'.'"'); 
    echo "\xef\xbb\xbf";
    
    $row = mysql_fetch_assoc($result);
    if ($row) {
        echocsv(array_keys($row));
    }
    
    while ($row) {
        echocsv($row);
        $row = mysql_fetch_assoc($result);
    }
    
    function echocsv($fields)
    {
        $separator = '';
        foreach ($fields as $field) {
            if (preg_match('/\\r|\\n|,|"/', $field)) {
                $field = '"' . str_replace('"', '""', $field) . '"';
            }
            echo $separator . $field;
            $separator = ',';
        }
        echo "\r\n";
    }
    

    How to export it to get all characters display correctly (make Excel understand utf-8) and to maintain table layout too(with rows and columns)

  • bukowski
    bukowski almost 11 years
    Thanks for info. I ended up using phpexcel to create xls file - no probs there phpexcel.codeplex.com/…