| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <?php
- namespace common\components;
- use yii\base\Component;
- class CsvExport extends Component
- {
- /**
- * 导出excel(csv)
- * @param array $data
- * @param array $headlist
- * @param $fileName
- */
- public function export($data = [], $headlist = [], $fileName)
- {
- try {
- $fileName = urlencode($fileName);
- header('Content-Type: application/vnd.ms-excel');
- header('Content-Disposition: attachment;filename*=utf-8' . "'zh_cn'" . iconv('utf-8', 'gbk', $fileName) . '.csv');
- header('Cache-Control: max-age=0');
- //打开PHP文件句柄,php://output 表示直接输出到浏览器
- $fp = fopen('php://output', 'a');
- //输出Excel列名信息
- foreach ($headlist as $key => $value) {
- //CSV的Excel支持GBK编码,一定要转换,否则乱码
- $headlist[$key] = iconv('utf-8', 'gbk', $value);
- }
- //将数据通过fputcsv写到文件句柄
- fputcsv($fp, $headlist);
- //计数器
- $num = 0;
- //每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
- $limit = 100000;
- //逐行取出数据,不浪费内存
- $count = count($data);
- for ($i = 0; $i < $count; $i++) {
- $num++;
- //刷新一下输出buffer,防止由于数据过多造成问题
- if ($limit == $num) {
- ob_flush();
- flush();
- $num = 0;
- }
- $row = $this->handleRowData($data[$i]);
- fputcsv($fp, $row);
- }
- exit();
- } catch (\Exception $exception) {
- dd($exception->getMessage());
- }
- }
- /**
- * 同时导出多个csv文件时,需要弄成压缩包一起下载
- * @data 导出数据
- * @headlist 第一行,列名
- */
- public function exportMultiple($data = array(), $headlist = array())
- {
- try {
- $fp = fopen('php://temp/maxmemory:1048576', 'w');
- if (false === $fp) {
- die('Failed to create temporary file');
- }
- //输出Excel列名信息
- foreach ($headlist as $key => $value) {
- //CSV的Excel支持GBK编码,一定要转换,否则乱码
- $headlist[$key] = iconv('utf-8', 'gbk', $value);
- }
- //将数据通过fputcsv写到文件句柄
- fputcsv($fp, $headlist);
- //计数器
- $num = 0;
- //每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
- $limit = 100000;
- //逐行取出数据,不浪费内存
- $count = count($data);
- for ($i = 0; $i < $count; $i++) {
- $num++;
- //刷新一下输出buffer,防止由于数据过多造成问题
- if ($limit == $num) {
- ob_flush();
- flush();
- $num = 0;
- }
- $row = $this->handleRowData($data[$i]);
- fputcsv($fp, $row);
- }
- rewind($fp);
- return $fp;
- } catch (\Exception $exception) {
- dd($exception);
- }
- }
- /**
- * 异步处理超大csv数据
- * @data 导出数据
- * @headlist 第一行,列名
- * @fileName 输出Excel文件名
- */
- public function ajaxExport($data = array(), $headlist = array(), $fileName)
- {
- try {
- $fileName = $fileName . '.csv';
- $newFilePath = \Yii::$app->basePath . \Yii::$app->urlManager->baseUrl . '/temp/goods/';
- if (!file_exists($newFilePath . $fileName)) {
- if (!is_dir($newFilePath)) {
- mkdir($newFilePath, 0777, true);
- }
- $fp = fopen($newFilePath . $fileName, 'a+');
- //输出Excel列名信息
- foreach ($headlist as $key => $value) {
- //CSV的Excel支持GBK编码,一定要转换,否则乱码
- $headlist[$key] = iconv('utf-8', 'gbk', $value);
- }
- //将数据通过fputcsv写到文件句柄
- fputcsv($fp, $headlist);
- }
- $fp = fopen($newFilePath . $fileName, 'a+');
- //计数器
- $num = 0;
- //每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
- $limit = 100000;
- //逐行取出数据,不浪费内存
- $count = count($data);
- for ($i = 0; $i < $count; $i++) {
- $num++;
- //刷新一下输出buffer,防止由于数据过多造成问题
- if ($limit == $num) {
- ob_flush();
- flush();
- $num = 0;
- }
- $row = $this->handleRowData($data[$i]);
- fputcsv($fp, $row);
- }
- return $fileName;
- } catch (\Exception $exception) {
- dd($exception->getMessage());
- }
- }
- //判断是否含有英文逗号,英文引号
- public function check($value)
- {
- if (!$this->checkJson($value)) {
- $isInt = is_int($value) ? true : false;
- $isFloat = is_float($value) ? true : false;
- $value = rtrim($value, "\r\n");
- $value = str_replace(",", ",", $value);
- $value = is_string($value) ? $value . "\t" : $value;
- $value = $isInt ? intval($value) : $value;
- $value = $isFloat ? floatval($value) : $value;
- }
- return $value;
- }
- public function handleRowData($data)
- {
- $row = $data;
- foreach ($row as $key => $value) {
- $value = $this->check($value);
- $row[$key] = mb_convert_encoding($value, 'GBK', 'UTF-8');
- }
- return $row;
- }
- // 判断是否为json数据
- private function checkJson($value)
- {
- $data = json_decode($value);
- if ($data && (is_object($data)) || is_array($data)) {
- return true;
- }
- return false;
- }
- }
|