Cakephp, PHP

Export data sang csv theo kiểu stream và không bị lỗi ký tự tiếng Nhật khi mở bằng Excel

Export dữ liệu sang csv trên Codeigniter:

  • ở Controller
$file_name = date('YmdHis') . '_store_information.csv';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_name);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');

$data_export = fopen('php://output', 'wb');

$array_header = [
"ID",
"Name",
]; // tạo title cho CSV
fwrite($data_export, "\xEF\xBB\xBF");// fix không bị lỗi font chữ tiếng Nhật trên excel
fputcsv($data_export, $array_header);
$page = 1;
$limit = 500;
$array = array_merge($this->input->get(), ['page' => $page, 'limit' => $limit]);

$data = $this->store_informations->get_stores($array, $limit);//lấy ra 500 bản ghi đầu tiên từ db,
if (!($data)) {
$this->session->set_flashdata('error_message', [
'データがありません。'
]);
redirect(BASEURL . '/admin/store_information', 'location');
} else {
do {
try {
if ($page != 1) {//kiểm tra số trang
$array_post = array_merge($this->input->get(), ['page' => $page, 'limit' => $limit]);
$data = $this->store_informations->get_stores($array_post, $limit);//lấy ra 500 bản ghi tiếp theo
}
if ($data) {
foreach ($data as $value) {
$array_data= [
$value['id'],
$value['name'],
];
fputcsv($data_export, $array_data);
}
}
$page ++; //tăng số trang lên
} catch (NotFoundException $e) {
exit();
}
} while (!empty($data));
fclose($data_export);
}
  • Trong Store_infomation model
public function get_stores($array = false, $set_limit = false) {
$offset = (!empty($array['page'])) ? ($array['page'] - 1) * PERPAGE : 0;//PERPAGE là limit trong dự án đang mặc định là 20
$limit = (!empty($array['limit'])) ? $array['limit'] : PERPAGE;
if ($set_limit) {
$offset = (!empty($array['page'])) ? ($array['page'] - 1) * $set_limit : 0;
$limit = (!empty($array['limit'])) ? $array['limit'] : $set_limit;
}//nếu có limit thì cần thay đổi biến $offset và biến $limit

if (!empty($array['name'])) {
$this->db->like('store_informations.store_number', $array['store_number']);
}

$this->db->limit($limit, $offset);
$this->db->order_by('store_informations.id', 'DESC');
// $this->db->join('statuses', 'corporates.status = statuses.id');
$this->db->select('store_informations.*');
$query = $this->db->get('store_informations');

if (!empty($query) && $query->num_rows() > 0) {
return $query->result_array();
}
return false;
}

Export dữ liệu sang csv trên Cakephp:

$this->paginate['limit'] = 500;//set litmit
$this->paginate['page'] = 1;//set page

//get name csv
$fileName = "List_Company" . date("YmdHis") . '.csv';
$this->autoRender = false;

$data = $this->Companies->getListCompaniesForCsv();//get all data from database

$data = $this->paginate($query)->toArray();
if (!($data)) {
$this->Flash->set(Configure::read('csvMsg.errNoDataCsv'));
$this->redirect($this->referer());
} else {
// title for csv
$title = Configure::read('title_csv_company');
$r = "";
$titleStr = "";
foreach ($title as $t_row) {
$titleStr .= $r . '"' . $t_row . '"';
$r = ",";
}

//render stream file csv
$ua = $_SERVER['HTTP_USER_AGENT'];
if (preg_match("/MSIE/i", $ua)) {
$fileName = mb_convert_encoding($fileName, "SJIS-win", "UTF-8");
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $fileName);

$stream = fopen('php://output', 'wb');

fwrite($stream, "\xEF\xBB\xBF");// fix không bị lỗi font chữ tiếng Nhật trên excel
fwrite($stream, $titleStr . "\r\n");

do {
try {
if ($this->paginate['page'] != 1) {
$data = $this->paginate($query);
}//kiểm tra số trang nếu khác 1 thì lấy ra tiếp 500 bản ghi
if ($data) {
foreach ($data as $dataCompany) {

$arr = array(
str_pad($dataCompany['id'], 6, '0', STR_PAD_LEFT),
$dataCompany['name'],
$dataCompany['comp_url'],,
);

$line = "";
$r = "";
foreach ($arr as $row) {
$line .= $r . '"' . $row . '"';
$r = ",";
}
fwrite($stream, $line . "\r\n");
}
}
$this->paginate['page'] ++;
} catch (NotFoundException $e) {
exit();
}
} while (!empty($data));
fclose($stream);
}