PHP、thinkphp5、分批导出大批量数据

思路:根据设置的每次导出的数据,分批写入到临时文件.txt中,进行压缩统一下载,最后删除临时.txt和压缩文件。(注意服务器文件夹是否有操作权限)

namespace app\common\my;

/**
 * 文件导出(ZIP格式)
 */
class FileExport
{

    private $fileName;

    private static $initialize;

    // 初始化
    public static function init()
    {
        if (is_null(self::$initialize)) {
            self::$initialize = new static;
        }
        return self::$initialize;
    }

    /**
     * 设置临时及导出文件名
     */
    public function setName(String $name = '')
    {
        $this->fileName = $name ?: date('Ymd') . '_' . md5(time());

        return $this;
    }

    //控制器分批次写入数据到文件防止内存不够
    public function writeData(Array $data, Array $field, int $is_head, string $txtFile){
        // 判断数据是否为空
        if (count($data) <= 0 || count($field) <= 0) die('数据长度错误');
        // 验证数据值字段与标题长度
        if (count($field) != count($data[0] ?? [])) die('数据值字段长度与标题字段长度不符');
        

        $context = '';
        if($is_head < 1){
            $context = implode("\t", $field) . "\r\n";
        }
        
        foreach ($data as $key => $value) {
            $context .= implode("\t", $value) . "\r\n";
        }

        // 写文件
        $handle = fopen($txtFile, 'a');
        fwrite($handle, $context);
        fclose($handle);
    }

    //压缩文件
    public function toZip(string $txtFile){
        $zipFile = \Env::get('runtime_path') . $this->fileName . '.zip';
        $zipArchive = new \ZipArchive();
        if ($zipArchive->open($zipFile, \ZipArchive::CREATE)) {
            $zipArchive->addFile($txtFile, basename($txtFile));
            $zipArchive->close();
            unlink($txtFile);
        }

        //下载文件
        $fp=fopen($zipFile ,"r");
        $file_size=filesize($zipFile);
        $zipName = explode(DIRECTORY_SEPARATOR, $zipFile);
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length:" . $file_size);
        Header("Content-Disposition: attachment; filename=" . $zipName[count($zipName) - 1]);
        $buffer=1024; $file_count=0;
        while(!feof($fp) && $file_count<$file_size){
            $file_con=fread($fp,$buffer);
            $file_count+=$buffer;
            echo $file_con;
        }
        fclose($fp);
        
        //下载完成后删除压缩包
        if($file_count >= $file_size)
        {
            unlink($zipFile);
        }
    }


    /**
     * 
     * 调用示例
     */

    // public function testExport(){
    //     $sqlLimit = 5000;
    //     $count = \Db::name('user')->count('id');
    //     $field = ['姓名','手机号码','参与时间'];
    //     $txtFile = \Env::get('runtime_path') . DIRECTORY_SEPARATOR . '用户数据-'.date('Y-m-d',time()) . '.txt';
    //     for($i = 0;$i < ceil($count/$sqlLimit);$i++){
    //         $list = \Db::name('user')->field('username,mobile,createtime')->limit($i*$sqlLimit,$sqlLimit)->select();
    //         FileExport::init()->writeData($list,$field,$i,$txtFile);
    //     }
    //     FileExport::init()->setName('用户数据-'.date('Y-m-d',time()))->toZip($txtFile);
    // }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值