• php不使用Office包实现上万条数据导出表格


    经过上传客户要求主副表迁出,又提出可以将某张表的数据导出excel,听着很简单,实际看数据表发现上万条数据,并且需要关联表查询相关字段,导出的表格才可以被客户看明白。

    要是使用office包目前后台内存耗尽,被迫停止运行,所以想要突破百万条数据导出需要另辟它路。所以就是使用了导出CSV并非excel文件。

    1、设置程序需要一直运行并设置运行内存(php提示过128M)by user 悦悦 https://www.cnblogs.com/nuanai

    2、数据查询出需要导出的数据字段(分页)

    3、分页进行导出文件并一起合并成压缩包后下载

    如果导出前需要某些条件筛选,那就需要在前端设置表单提交筛选条件(不过多介绍)

    导出配置的编写,需要设置文件路径、名称、表头等基本信息 by user 悦悦 https://www.cnblogs.com/nuanai

    复制代码
     1 //让程序一直运行
     2 set_time_limit(0); 
     3 //设置程序运行内存---php提示过128M
     4 ini_set('memory_limit', '128M');
     5 //文件名使用的日期命名
     6 $fileName = date('YmdHis', time());
     7 //文件保存位置    
     8 $destPath = ROOT_PATH . 'public' .DS. 'uploads'.DS.'download'.DS.$fileName. '.csv';
     9 // 打开文件句柄,准备写入数据  
    10 $fileHandle = fopen($destPath, 'w');
    11 // 检查文件句柄是否成功打开  
    12 if ($fileHandle === false) {
    13     die('无法打开文件: ' . $fileHandle);
    14 }
    15 //表头
    16 fputcsv($fileHandle,['序号', '产品名称', '产品型号','工名称','条码1','条码2','状态','时间']);
    17 //条数
    18 $nums = 10000;
    19 //数据表的总数
    20 $count = $this->model->count();
    21 $step = ceil($count/$nums);
    复制代码

    查询数据,这边需要关联表查询用的是左查询的方式,通过for循环进行每页的写入文件

    时间戳格式化直接使用了sql语句转换,省去进入循环后再次循环格式化  by user 悦悦 https://www.cnblogs.com/nuanai

     1 FROM_UNIXTIME(updatetime, '%Y-%m-%d %H:%i:%s') 

    需要注意就是写入CSV之前需要对字段转一维数组

    复制代码
     1 for($i=0;$i<$step;$i++){
     2     $start = $i*$nums;
     3     $result = $this->model->alias('pd')
     4         ->join('products ps','ps.id=pd.product_id','LEFT')
     5         ->join('step st','st.id=pd.step_id','LEFT')
     6         ->field("pd.id,ps.name,ps.spec,st.name as sname,pd.barcode,pd.barnum,pd.isin,FROM_UNIXTIME(pd.updatetime, '%Y-%m-%d %H:%i:%s') AS uptime")->order("pd.updatetime","desc")->limit($start,$nums)->select();
     7         
     8     foreach ($result as $K=> &$item) {
     9         // 转换每行数据为一维数组
    10         $rowData = [
    11             $item['id'],
    12             $item['name'],
    13             $item['spec'],
    14             $item['sname'],
    15             $item['barcode'],
    16             $item['barnum'],
    17             $item['isin'],
    18             $item['uptime']
    19         ];
    20         
    21         // 写入 CSV
    22         fputcsv($fileHandle, $rowData);
    23     }
    24     
    25 }
    复制代码

    开启了文件句柄,记得关闭 

     1 // 关闭文件句柄 2 fclose($fileHandle); 

    到这里就是可以将上万条数据导出CSV文件了,为了减少客户下载时间,又进行了对文件压缩,客户下载压缩文件。 by user 悦悦 https://www.cnblogs.com/nuanai

    这里使用的调用方法,需要传入参数:文件名  

    复制代码
     1 if (!class_exists('ZipArchive')) {
     2     throw new Exception(__('ZinArchive not install'));
     3 }
     4 $downloadPath = ROOT_PATH . 'public' .DS. 'uploads'.DS.'download'.DS; //服务器中文件zip保存的位置
     5 $destDir =  $downloadPath.$zipName . '.zip'; //全路径
     6 $zip = new \ZipArchive;  //压缩类
     7 $zip->open($destDir, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
     8 $csvDir = $downloadPath .$csvFileName.'.csv'; //需要压缩文件的全路径
     9 $fileName = basename($csvDir); //获取文件名
    10 $zip->addFile($csvDir, $fileName);
    11 $zip->close();
    12 $zipFilename = basename($destDir);
    13 // 设置HTTP头信息  
    14 header('Content-Type: application/octet-stream');  
    15 header('Content-Disposition: attachment; filename="'.$zipFilename.'"');  
    16 header('Content-Length: ' . filesize($destDir));
    17 // 读取并输出ZIP文件内容  
    18 readfile($destDir);
    19 // 删除临时ZIP文件(可选)  
    20 unlink($destDir);
    复制代码

    这边再生成压缩文件后,并删除了云服务器中的压缩文件,如果服务器空间允许看个人选择;如果想要删除服务器中的CSV文件,需要在生成压缩文件后进行删除操作

    在第一个方法的最后添加如下代码:保存文件的路径   by user 悦悦 https://www.cnblogs.com/nuanai

     1 unlink($destPath); 

    到这里就可以实现客户通过后台进行上万条数据的导出下载功能了,就是有一个弊端,需要等待浏览器跳出下载框,哎,给客户说一下耐心生成文件吧。

  • 相关阅读:
    Python干货|time模块和datetime模块打印时间的特殊用法
    ResNet
    尚硅谷Flink(二)DStream API
    利用干扰源模型确定多通道音频信号盲源分离
    day1项目配置
    【Linux】提权问题
    【uml期末复习】统一建模语言大纲
    Transferrin-PEG-PMMA 转铁蛋白-聚乙二醇-聚甲基丙烯酸甲酯,F-PEG-PBA/PAE/PPS
    ubuntu安装pgsql16
    SRVCC关键场景及Log分析
  • 原文地址:https://www.cnblogs.com/nuanai/p/18267036