利用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();
}
上一篇: 百度网站权重是什么?站长应如何提升网站的百度权重?
下一篇: window.print铺满纸张打印