YII读写文件

来zm好长时间了  对yii有了一定的了解,最近做了一个需求觉得有必要进行总结:

任务需求:

1.上传:从一张数据表a中按照已经拟定的条件筛选出数据然后写入另外一张表b中,a中大概有33万条数据  77个字段,筛选的数据有接近10万条数据。

2.分发:然后再从这10万条数据中进行随机分配给N个人N条,然后生成excel文档。

3:下载  对文档进行打包下载;

4:上传结果文档跟新数据库。

做这个需求用了两个星期的时间  是遇到无数个坎。显示遇到条件写不对。数据筛选不正确,

而后是数据分发  生成文档   最后是下载 打包压缩

在生成文档那刚开始用的是上传csv文件  后来突然csv文件读取乱码,无法处理。我的csv和客服的csv文件上传一个能读   一个不能读,然后就改成xls就能都读取了。

然后生成dir目录的时候是生成xls文档,然后还上传这个文档。

用csv文件下载能下载  上传读取时乱码,所以干脆统一格式  生成xls文件还上传xls文件。

writeXlsx和readXlsx 这一对方法。

writeCsv=>readCsv 这以是一对方法  只能用于csv的文件读取。

最后下载:下载之前对文件进行打包,一开始打的报都带有服务器的跟路径

下载代码如下:

    private function create_zip($path,$filename){
        $zip = new \ZipArchive();
        if($zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
            $this->addFileToZip($path, $zip);//调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
            $zip->close(); //关闭处理的zip文件
        }
    }

    private function addFileToZip($path,$zip){
        $handler=opendir($path); //打开当前文件夹由$path指定。
        while(($filename=readdir($handler))!==false){
            if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
                if(is_dir($path."/".$filename)){
                    $this->addFileToZip($path."/".$filename, $zip);// 如果只写第一个的话   文件会带类路径(从服务器的根目录开始)
                }else{
                    $zip->addFile($path."/".$filename,$filename);
                }
            }
        }
        closedir($handler);
    }

    private  function deleteDirFile($dirpath){
        $handler=opendir($dirpath); //打开当前文件夹由$path指定。
        while(($filename=readdir($handler))!==false){
            if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
                if(is_dir($dirpath."/".$filename)){
                    $this->deleteDie($dirpath."/".$filename);
                }else{
                    unlink($dirpath."/".$filename);
                }
            }
        }
        closedir($handler);
    }
    // 是否展示下载按钮
    public function actionIsDownload(){
        // 判断是否已经生成lawcase2021-11-11的目录  判断其中的文件个数
        $date = date('Y-m-d',time());
        $path = Yii::getAlias('@runtime/lawcase/'.$date);
        if(!is_dir($path)){
            return false;
        }
        $filename = Yii::getAlias('@runtime/lawcase/lawcase'.$date.'.csv');
        // 读取上传的分配任务文档
        $staffarr  =  $this->GetStaffInfo($filename);
        $peoplelen = count($staffarr);
        $dir   = opendir($path);
        $filen = 0;
        while($filename = readdir($dir)) {
            if($filename!="." && $filename !="..") {
                $filename = $path."/".$filename;
                if(is_dir($filename)) {
//                    $dirn++;
//                    getdirnum($filename); //递归,就可以查看所有子目录
                } else {
                    $filen++;
                }
            }
        }
        closedir($dir);
        if($peoplelen == $filen){
            return true;
        }
    }
// 案源C
            if($value['case_c'] > 0){
                $start = 1;
                $sql = "SELECT * FROM public_sea WHERE registrant_name<>'".$value['name'] ."' AND case_dict = 'C' order by rand() limit 1";
                // 循环插入历史表
                while(true){
                    $case_rand = $query->createCommand($sql)->queryOne();  // 随机分配一条案源给客服和谈案
                    if(empty($case_rand)){
                        break;
                    }
                    if(!in_array($case_rand['case_id'],$his_ids)){
                        // 插入历史表中
                        $hres = $this->actionInsertHistory($case_rand,$value['name']);
                        if($hres === "ok"){
                            $case_rand['name']    = $value['name'];
                            $case_rand['case_id'] = $case_rand['case_id']."\t";
                            $staff_case_arr[] = $case_rand;  // 加入用户数组  导出使用
                            $start++; // 计算没个人导出的案源总数
                            array_push($his_ids,$case_rand['case_id']);
                        }elseif($hres === "exists"){
                            continue;
                        }else{
                            $transaction->rollBack();
                            return ['status'=>false,'toast'=>"分配结果插入历史表失败".$hres];
                        }
                    }else{
                        continue;
                    }
                    if($start > $value['case_c']){
                        break;
                    }
                }
            }

上面是根据条件从表b中随机筛入一条数据给一个人,如果历史表c有则在循环随机抽一条数据,历史表没有就插入历史表。

这个一开始做的事  循环完一个人的任务就找到分发的数据,就导出这个人的表,但是导出的表出现了名称和文件重复。找不到原因就换个思路写。将所有人的数据全部获取到存在缓存中

然后统一一次性生成10个人的文档文档。这次就可以了。(有问题并且找不到原因就换个思路做

 其实一开始的时候生成公海的内容页出现了一次问题  ,因为a表数据过大找到10万条数据,然后循环插入b表 就导致内存溢出,后来就分页写的(后来想到有yield和ob函数,不知道对打数据循环有没有好处

就先记到这吧   有想起来的 以后再加

你可能感兴趣的:(php,php,mysql,nginx)