ExecReport.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\command;
  4. use PHPUnit\Exception;
  5. use think\console\Command;
  6. use think\console\Input;
  7. use think\console\input\Argument;
  8. use think\console\input\Option;
  9. use think\console\Output;
  10. use think\facade\Db;
  11. use think\facade\Cache;
  12. class ExecReport extends Command
  13. {
  14. public $redis=[];
  15. protected function configure()
  16. {
  17. ini_set("memory_limit","512M");
  18. // 指令配置
  19. $this->setName('ExecReport')
  20. ->setDescription('the hello command');
  21. }
  22. protected function execute(Input $input, Output $output)
  23. {
  24. $this->redis=Cache::store("redis");
  25. $iscgd = $this->redis->get("exreport");
  26. if($iscgd==0){
  27. $this->redis->set("exreport",1);
  28. }else{
  29. return;
  30. }
  31. try {
  32. if ($this->redis->handler()->llen('execreport') > 0) {
  33. $data = $this->redis->handler()->rpop('execreport');
  34. $user_info = json_decode($data, true);
  35. $rel = $this->checkJob($user_info);
  36. if ($rel) {
  37. $this->doData($user_info);
  38. }
  39. }
  40. $this->redis->set("exreport", 0);
  41. $output->writeln('queuecus');
  42. }catch (\Exception $e){
  43. $this->redis->set("exreport", 0);
  44. $output->writeln('queuecus');
  45. }
  46. }
  47. protected function checkJob($data){
  48. if($data['id']!=''){
  49. $info = Db::name("exec")->where(["id"=>$data['id']])->find();
  50. if($info['status']!=1){
  51. return false;
  52. }
  53. }else{
  54. return false;
  55. }
  56. return true;
  57. }
  58. protected function doData($data){
  59. $diff = $this->monthDiff($data['start'],$data['end']);
  60. $zipfile=[];
  61. $dir = "/storage/report/".date("YmdHis")."/";
  62. foreach ($diff as $value){
  63. $start = $value." 00:00:00";
  64. $end = date("Y-m-t",strtotime($value))." 23:59:59";
  65. $sql =str_replace(["%s","%t"],[$start,$end],$data['exec_sql']);
  66. $list = Db::query($sql);
  67. if(empty($list)){
  68. continue;
  69. }
  70. $header = array_keys($list[0]);
  71. array_walk($list, function (&$v) {
  72. $v = array_values($v);
  73. });
  74. $zipfile []=$this->execfile($value.'月份'.$data['name'],$header,$list,$dir);
  75. }
  76. if(empty($zipfile)){
  77. $info=[];
  78. $info['status']=2;
  79. $info['remark']='文件生成失败';
  80. $info['updatetime']=date("Y-m-d H:i:s");
  81. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  82. return ;
  83. }
  84. $zip=$this->addzipfile($zipfile,$data['name']);
  85. if(is_file(root_path() . 'public'.$zip)){
  86. $info=[];
  87. $info['status']=2;
  88. $info['down_url']=$zip;
  89. $info['expiretime']=date("Y-m-d H:i:s",time()+7*24*3600);
  90. // $info['updatetime']=date("Y-m-d H:i:s");
  91. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  92. return ;
  93. }else{
  94. $info=[];
  95. $info['status']=2;
  96. $info['remark']='文件生成失败';
  97. $info['updatetime']=date("Y-m-d H:i:s");
  98. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  99. return ;
  100. }
  101. }
  102. protected function execfile($fileName,$headArr,$data,$root_dir){
  103. if(is_file(root_path() . 'public'.$root_dir.$fileName)){
  104. unlink(root_path() . 'public'.$root_dir.$fileName);
  105. }
  106. $objPHPExcel = new \PHPExcel();
  107. $objPHPExcel->getProperties();
  108. $keyA = 0; // 设置表头
  109. foreach ($headArr as $v) {
  110. $colum = \PHPExcel_Cell::stringFromColumnIndex($keyA);
  111. $objPHPExcel->setActiveSheetIndex(0)->setCellValue($colum . '1', $v);
  112. $keyA += 1;
  113. }
  114. $column = 2;
  115. $objActSheet = $objPHPExcel->getActiveSheet();
  116. foreach ($data as $key => $rows) { // 行写入
  117. $span = 0;
  118. foreach ($rows as $keyName => $value) { // 列写入
  119. //判断数据是否有数组,如果有数组,转换成字符串
  120. if(is_array($value)){
  121. $value = implode("、", $value);
  122. }
  123. $objActSheet->setCellValue(\PHPExcel_Cell::stringFromColumnIndex($span) . $column, $value);
  124. $span++;
  125. }
  126. $column++;
  127. }
  128. $file = $fileName. ".xls";
  129. $dir =root_path() . 'public'.$root_dir;
  130. if(!is_dir($dir)){
  131. mkdir($dir,0777,true);
  132. }
  133. $objPHPExcel->setActiveSheetIndex(0); // 设置活动单指数到第一个表,所以Excel打开这是第一个表
  134. $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
  135. $objWriter->save($dir . $file); // 文件通过浏览器下载
  136. return $dir.$file;
  137. }
  138. public function monthDiff($start,$end){
  139. $start = date("Y-m",strtotime($start))."-01";
  140. $end = date("Y-m",strtotime($end))."-01";
  141. $data=[];
  142. while (strtotime($start)<=strtotime($end)){
  143. $data[]=$start;
  144. $start = date('Y-m-d', strtotime("$start +1 month"));
  145. }
  146. return $data;
  147. }
  148. public function addzipfile($filelist,$zipname){
  149. $datetime = date("YmdHis");
  150. $zip_dir="/storage/zip/".$datetime."/".$zipname.".zip";
  151. $file_dir =root_path()."public/storage/zip/".$datetime."/".$zipname.".zip";
  152. $saveDir = root_path()."public/storage/zip/".$datetime."/";
  153. if(!is_dir( $saveDir)){
  154. mkdir($saveDir,0777,true);
  155. }
  156. # 5.1 文件打包,提示:使用本类,linux需开启zlib,windows需取消php_zip.dll前的注释
  157. $zip = new \ZipArchive ();
  158. # 5.2 文件不存在则生成一个新的文件 用CREATE打开文件会追加内容至zip
  159. if ($zip->open($file_dir, \ZipArchive::OVERWRITE) !== true && $zip->open($file_dir, \ZipArchive::CREATE) !==
  160. true) echo '无法打开文件或者文件创建失败';
  161. # 5.3 批量写入压缩包
  162. foreach ($filelist as $value){
  163. $fileName=basename($value);
  164. $filedir=pathinfo($value);
  165. $zip->addEmptyDir($fileName);
  166. // @$zip->addFile($v['file_path'], 'resume'.DIRECTORY_SEPARATOR.basename($headername));
  167. @$zip->addFile($value,$fileName.DIRECTORY_SEPARATOR.basename($value));
  168. # 5.4 关闭压缩包写入
  169. $dir = $filedir['dirname'];
  170. //@unlink($value);
  171. // @$this->deldir($filedir['dirname']);
  172. }
  173. $zip->close();
  174. @$this->deldir($dir);
  175. return $zip_dir;
  176. }
  177. public function deldir($path){
  178. //如果是目录则继续
  179. if(is_dir($path)){
  180. //扫描一个文件夹内的所有文件夹和文件并返回数组
  181. $p = scandir($path);
  182. //如果 $p 中有两个以上的元素则说明当前 $path 不为空
  183. if(count($p)>2){
  184. foreach($p as $val){
  185. //排除目录中的.和..
  186. if($val !="." && $val !=".."){
  187. //如果是目录则递归子目录,继续操作
  188. if(is_dir($path.$val)){
  189. //子目录中操作删除文件夹和文件
  190. deldir($path.$val.'/');
  191. }else{
  192. //如果是文件直接删除
  193. unlink($path.'/'.$val);
  194. }
  195. }
  196. }
  197. }
  198. }
  199. //删除目录
  200. return rmdir($path);
  201. }
  202. }