欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用PHPexcel生成对应多张excel表格并打包提供下载功能(生成的表格里面是包含图片的)

程序员文章站 2022-06-14 08:17:31
...

思路:点击下载触发download方法==>
先生成文件夹(用于保存生成的excel文件并且后期压缩文件夹及删除文件夹方法操作)==>
使用PHPExcel生成对应的excel表格并放置到我们生成的文件夹中去==>
生成对应的文件夹并进行压缩处理==>使用文件头输出该压缩包到浏览器并提供下载==>
删除已经生成的文件夹以及文件==>
优化

直接上代码


        public function download()
        {
            $id = input('id', '', 'intval');
            //状态为已上传才可以去下载 (状态为 3 )
//            $status = \app\admin\model\ActivityShop::getActivityShopStatusValue($id);
//            if($status !=3){
//                $this->error('用户未上传完相关资料!');
//            }
            //引入PHPExcel插件
            vendor("PHPExcel.Classes.PHPExcel");
            //数据查询
            $action_id = input('act_id', '', 'intval');
            $m_id  = Db::name('activity_shop')->where('act_id', $action_id)->value('m_id');
            //文件夹名称以及文件的命名规范
            $dir_name = Db::name('activity_shop')->where('id',$id)->where('act_id',$action_id)->value('shop_name');
            $zipName  =$dir_name;
            $pinyin = new Pinyin();
            $dir_name     = trim( $pinyin->strtopin($dir_name) ) ;
            $shop_name    = trim( $pinyin->strtopin('商户') );
            $goods_name   = trim( $pinyin->strtopin('产品') );
            $coupon_name  = trim( $pinyin->strtopin('优惠券') );
            $present_name = trim( $pinyin->strtopin('礼品') );
            //新建临时文件夹并以活动门店为命名
            if(!is_dir('uploads/'.$dir_name)){
                mkdir(iconv('utf-8', 'gbk','uploads/'.$dir_name));
            }
            //生成该门店的基本信息excel
            $shopExcel   = new \PHPExcel();
            $shopExcel->setActiveSheetIndex(0);//选中我们生成的excel文件的第一张工作表
            $shop_sheet = $shopExcel->getActiveSheet();//获取到选中的工作表,方面后面数据插入操作
            //获取该活动门店的基本信息
            $shop_res   = shopModel::getOneActivityShopCopy($id);
            foreach($shop_res as $kk=>$vv  ){
                $shop_res[$kk]['shop_logo'] =ltrim($shop_res[$kk]['shop_logo'],'/');
            }
            $shop_arr   =[
                'shop_name' =>'门店名称',
                'description' =>'描述',
                'keywords' =>'关键词',
                'content' =>'详细介绍',
                'shop_logo' =>'门店logo',
//                'add_time'  =>'添加时间',
            ];
            array_unshift($shop_res, $shop_arr);
            $shops_time = 0;//因为我们生成的excel表格的行数是从1开始,所以我们预先设置好一个变量,供下面foreach循环的$k使用
            foreach ($shop_res as $k => $v) {
                $shops_time=$k+1;//表示从生成的excel表格的第一行开始插入数据
                $shop_sheet->setCellValue('A' . $shops_time, $v['shop_name'])
                    ->setCellValue('B' . $shops_time, $v['description'])
                    ->setCellValue('C' . $shops_time, $v['keywords'])
                    ->setCellValue('D' . $shops_time, $v['content']);
//                ->setCellValue('F' . $shops_time, $v['add_time']);
                //第一次循环不出图片
                if($shops_time > 1){
                    $objDrawing = new \PHPExcel_Worksheet_Drawing();
                    $objDrawing->setPath($v['shop_logo']);
                    $objDrawing->setHeight(300);
                    $objDrawing->setWidth(300);
                    $objDrawing->setCoordinates('E'. $shops_time);
                    $objDrawing->setWorksheet($shopExcel->getActiveSheet());
                }
            }
            //额外属性
            $shopExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(150);
            $shopExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(30);
            $shopExcel->getDefaultStyle()->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
            $shopExcel->getDefaultStyle()->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
            $phpWriter = \PHPExcel_IOFactory::createWriter($shopExcel,'Excel5');
            $phpWriter->save('uploads/'.$dir_name."/$shop_name.xls");//生成表格( 活动 )
            //生成该门店的 产品excel
            $goodsExcel  = new \PHPExcel();
            $goodsExcel->setActiveSheetIndex(0);//选中我们生成的excel文件的第一张工作表
            $goods_sheet = $goodsExcel->getActiveSheet();//获取到选中的工作表,方面后面数据插入操作
            //获取该活动门店的活动产品
            $goods_res   = ActivityGood::getGoodsByActIdAndMid($action_id,$m_id);
            foreach($goods_res as  $kkk=>$vvv ){
                $goods_res[$kkk]['pro_pic'] =ltrim($goods_res[$kkk]['pro_pic'],'/');
            }
            $goods_arr   =[
               'pro_title' =>'产品标题',
               'pro_attr' =>'产品属性',
               'market_price' =>'市场价',
               'price' =>'活动价',
               'pro_dec' =>'产品简介',
               'content' =>'产品详情',
//               'add_time' =>'添加时间',
               'pro_pic' =>'产品图片',
            ];
            array_unshift($goods_res, $goods_arr);
            $goods_time = 0;//因为我们生成的excel表格的行数是从1开始,所以我们预先设置好一个变量,供下面foreach循环的$k使用
            foreach ($goods_res as $k => $v) {
                $goods_time=$k+1;//表示从生成的excel表格的第一行开始插入数据
                $goods_sheet->setCellValue('A' . $goods_time, $v['pro_title'])
                    ->setCellValue('B' . $goods_time, $v['pro_attr'])
                    ->setCellValue('C' . $goods_time, $v['market_price'])
                    ->setCellValue('D' . $goods_time, $v['price'])
                    ->setCellValue('E' . $goods_time, $v['pro_dec'])
                    ->setCellValue('F' . $goods_time, $v['content']);
//                    ->setCellValue('G' . $goods_time, date('Y-m-d H:i:s',$v['add_time']));
                //第一次循环不出图片
                if($goods_time > 1){
                    $objDrawing = new \PHPExcel_Worksheet_Drawing();
                    $objDrawing->setPath($v['pro_pic']);
                    $objDrawing->setHeight(300);
                    $objDrawing->setWidth(300);
                    $objDrawing->setCoordinates('G'. $goods_time);
                    $objDrawing->setWorksheet($goodsExcel->getActiveSheet());
                }
            }
            //额外属性
            $goods_sheet->setCellValue('I' . '1', '');
            $goodsExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(150);
            $goodsExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(30);
            $goodsExcel->getDefaultStyle()->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
            $goodsExcel->getDefaultStyle()->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
            $phpWriter = \PHPExcel_IOFactory::createWriter($goodsExcel,'Excel5');
            $phpWriter->save('uploads/'.$dir_name."/$goods_name.xls");//生成表格( 活动 )
            //生成该活动的 优惠券excel
            $couponExcel = new \PHPExcel();
            $couponExcel->setActiveSheetIndex(0);//选中我们生成的excel文件的第一张工作表
            $sheet = $couponExcel->getActiveSheet();//获取到选中的工作表,方面后面数据插入操作
            //数据查询
            $res = ActivityCoupon::getCouponsByActIdCopy($action_id, $m_id);  //获取到要导出的数据,如果有限制条件可以加入where方法
            //此处设置的是生成的excel表的第一行标题
            $arr = [
                'co_name' => '优惠券名称',
                'co_description' => '优惠简介描述',
                'co_content' => '详细介绍',
                'co_total_price' => '多少价格可用',
                'co_price' => '优惠价格',
                'co_amount' => '优惠券总量',
//                'add_time' => '添加时间',
            ];
            array_unshift($res, $arr);//将我们上面手动设置的标题信息放到数组中,作为第一行写入数据表
            $time = 0;//因为我们生成的excel表格的行数是从1开始,所以我们预先设置好一个变量,供下面foreach循环的$k使用
            foreach ($res as $k => $v) {
                $time=$k+1;//表示从生成的excel表格的第一行开始插入数据
                $sheet->setCellValue('A' . $time, $v['co_name'])
                ->setCellValue('B' . $time, $v['co_description'])
                ->setCellValue('C' . $time, $v['co_content'])
                ->setCellValue('D' . $time, $v['co_total_price'])
                ->setCellValue('E' . $time, $v['co_price'])
                ->setCellValue('F' . $time, $v['co_amount']);
//                ->setCellValue('G' . $time, date('Y-m-d H:i:s',$v['add_time'] ));
            }
            $phpWriter = \PHPExcel_IOFactory::createWriter($couponExcel,'Excel5');
            $phpWriter->save('uploads/'.$dir_name."/$coupon_name.xls");//生成表格( 优惠券 )
//          生成该活动的 礼品excel
            $presentExcel = new \PHPExcel();
            $presentExcel->setActiveSheetIndex(0);//选中我们生成的excel文件的第一张工作表
            $presentSheet = $presentExcel->getActiveSheet();//获取到选中的工作表,方面后面数据插入操作
            //数据查询
            $present_res = Db::name('activity_present')->where('act_id',$action_id)->where('m_id',$m_id)->select();
            //此处设置的是生成的excel表的第一行标题
            $present_arr = [
                'title' => '礼品名称',
                'number' => '礼品数量',
//                'add_time' => '添加时间',
//                'update_time' => '修改时间',
            ];
            array_unshift($present_res, $present_arr);//将我们上面手动设置的标题信息放到数组中,作为第一行写入数据表
            $present_time = 0;//因为我们生成的excel表格的行数是从1开始,所以我们预先设置好一个变量,供下面foreach循环的$k使用
            foreach ($present_res as $k => $v) {
                $present_time=$k+1;//表示从生成的excel表格的第一行开始插入数据
                $presentSheet->setCellValue('A' . $present_time, $v['title'])
                    ->setCellValue('B' . $present_time, $v['number']);
//                    ->setCellValue('C' . $present_time, $v['add_time']);
//                    ->setCellValue('D' . $present_time, date( 'Y-m-d H:i:s',$v['update_time']) );
            }
            $presentWriter = \PHPExcel_IOFactory::createWriter($presentExcel,'Excel5');
            $presentWriter->save('uploads/'.$dir_name."/$present_name.xls");//生成表格( 礼品 )

            //需要打包压缩的文件路径
            $files =array(
                'uploads/'.$dir_name.'/'.$shop_name.'.xls',
                'uploads/'.$dir_name.'/'.$goods_name.'.xls',
                'uploads/'.$dir_name.'/'.$coupon_name.'.xls',
                'uploads/'.$dir_name.'/'.$present_name.'.xls',
            );
//            dump($zipName);die();
            $this->down($dir_name,$files,$zipName);
        }

    /**
     * 打包相关文件并输出到浏览器提供下载
     * @param $zipName
     * @param $files
     * @param $name
     */
    public function down($zipName,$files,$name){
        $dir     = 'uploads/'.$zipName;
        $zipName = 'uploads/'.$zipName.'.zip';
        $zip = new \ZipArchive;//使用本类,linux需开启zlib,windows需取消php_zip.dll前的注释
        if ($zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE)!==TRUE) {
            exit('无法打开文件,或者文件创建失败');
        }
        foreach($files as $val){
            //$attachfile = $attachmentDir . $val['filepath']; //获取原始文件路径
            if(file_exists($val)){
                $zip->addFile($val, basename($val));//第二个参数是放在压缩包中的文件名称,如果文件可能会有重复,就需要注意一下
            }
        }
        $zip->close();//关闭
        if(!file_exists($zipName)){
            exit("无法找到文件"); //即使创建,仍有可能失败
        }
        //如果不要下载,下面这段删掉即可,如需返回压缩包下载链接,只需 return $zipName;
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header('Content-disposition: attachment; filename='.basename($zipName)); //文件名
        header("Content-Type: application/zip"); //zip格式的
        header("Content-Transfer-Encoding: binary"); //告诉浏览器,这是二进制文件
        header('Content-Length: '. filesize($zipName)); //告诉浏览器,文件大小
        @readfile($zipName);
        //删除生成的文件夹以及xsl的文件
        Activity::delDir($dir);
        unlink($zipName);
    }

这个是可参考的生成excel文件的步骤,按照来做一般没啥问题
接下来我们看看要导出的表,这里重新创建一张简单的表作为演示:
而我们想要的导出的excel的结果为:
最后,我们的实现逻辑如下:

public function export(){
 if(request()->isPost()){
 $phpexcelSrc=APP_PATH.'../phpexcel/PHPExcel.php';//我们将手动下载的phpexcel放置到了application同级目录
 include "$phpexcelSrc";//引入phpExcel
 $phpexcel=new \PHPExcel();//实例化PHPExcel类对象,方便操作即将生成的excel表格
 $phpexcel->setActiveSheetIndex(0);//选中我们生成的excel文件的第一张工作表
 $sheet=$phpexcel->getActiveSheet();//获取到选中的工作表,方面后面数据插入操作
 $res=db('order')->field('uname,price,num,goods_name')->select();//获取到要导出的数据,如果有限制条件可以入where方法
 //此处设置的是生成的excel表的第一行标题
 $arr=[
 'uname'=>'用户名',
 'price'=>'商品单价',
 'num'=>'购买数量',
 'goods_name'=>'商品名称',
 ];
 array_unshift($res, $arr);//将我们上面手动设置的标题信息放到数组中,作为第一行写入数据表
 $currow=0;//因为我们生成的excel表格的行数是从1开始,所以我们预先设置好一个变量,供下面foreach循环的$k使用
 foreach ($res as $k => $v) {
 $currow=$k+1;//表示从生成的excel表格的第一行开始插入数据
 $sheet->setCellValue('A'.$currow,$v['uname'])//为A列循环插入用户名数据
 ->setCellValue('B'.$currow,$v['price'])//为B列循环插入价格数据
 ->setCellValue('C'.$currow,$v['num'])//为C列循环插入购买数量数据
 ->setCellValue('D'.$currow,$v['goods_name'])//为D列循环插入商品名称数据
 ;
}
 header('Content-Type: application/vnd.ms-excel');//设置下载前的头信息
 header('Content-Disposition: attachment;filename="ceshi.xlsx"');
 header('Cache-Control: max-age=0');
 $phpwriter=new \PHPExcel_Writer_Excel2007($phpexcel
);//此处的2007代表的是高版本的excel表格
 $phpwriter->save('php://output');//生成并下载excel表格
 return;
 }
 return view();
}
相关标签: PHPExcel