require('./db/dbManager.php'); require('./session.php'); require('./department_utils.php'); class ExportCSV{ function __construct(){ $this->db=new dbManager(); $this->out = fopen('php://output', 'w'); } function output(&$row){ for($i=0;$i<count($row);$i++){ $row[$i]=iconv('utf-8','gb18030',$row[$i]); } fputcsv($this->out,$row); } function user($opts){ if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; $fileName=$name.'-用户列表'; }else{ $department=0; $fileName='全部部门-用户列表'; } if(isset($opts['download'])){ //header('Content-Disposition: attachment;filename="'.$fileName.'.csv"'); $this->set_filename($fileName.'.csv'); } $h=['部门','用户名','姓名','手机','工号','身份']; $this->output($h); $sql='SELECT COUNT(*) FROM users'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' WHERE DepartmentId IN '.$deps; } $total=$this->db->querySingle($sql); $sql='SELECT d.DepartmentName,u.Username,u.Name,u.Phone,u.empno,r.name FROM users u'; $sql.=' LEFT JOIN department d ON d.ID=u.DepartmentId'; $sql.=' LEFT JOIN role r ON r.id=u.role'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' WHERE DepartmentId IN '.$deps; } $sql.=' LIMIT ?,10'; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++) $this->output($arr[$j]); } } function time_range($b,$e){ return date('Ymd',$b).'-'.date('Ymd',$e); } function exam($opts){ if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $begin=(int)$opts['begin']; $end=(int)$opts['end']; $begin_str=date('Y-m-d H:i:s',$begin); $end_str=date('Y-m-d H:i:s',$end); $fileName=$name.'-考试-'.$this->time_range($begin,$end); if(isset($opts['download'])){ //header('Content-Disposition: attachment;filename="'.$fileName.'.csv"'); $this->set_filename($fileName.'.csv'); } $h=['部门','考试名','时间','时长(分钟)','总分','及格线(百分制)']; $this->output($h); $sql='SELECT COUNT(*) FROM exam e'; $sql.=' WHERE e.ExamTime BETWEEN ? AND ?'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND DepartmentId IN '.$deps; } $total=$this->db->querySingle($sql,[$begin_str,$end_str]); $sql='SELECT d.DepartmentName,e.ExamName,e.ExamTime,e.ExamDuration,e.Score,e.PassScore FROM exam e'; $sql.=' LEFT JOIN department d ON d.ID=e.DepartmentId'; $sql.=' WHERE e.ExamTime BETWEEN ? AND ?'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND DepartmentId IN '.$deps; } $sql.=' LIMIT ?,10'; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$begin_str,$end_str,$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++){ if(!$arr[$j][0]) $arr[$j][0]='全部部门'; $this->output($arr[$j]); } } } function grade($opts){ if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $begin=(int)$opts['begin']; $end=(int)$opts['end']; $begin_str=date('Y-m-d H:i:s',$begin); $end_str=date('Y-m-d H:i:s',$end); $fileName=$name.'-考试成绩-'.$this->time_range($begin,$end); if(isset($opts['download'])){ //header('Content-Disposition: attachment;filename="'.$fileName.'.csv"'); $this->set_filename($fileName.'.csv'); } $h=['部门','名字','考试名','时间','总分','分数']; $this->output($h); $sql='SELECT COUNT(*) FROM grade g'; $sql.=' LEFT JOIN exam e ON e.ID=g.ExamId'; $sql.=' LEFT JOIN users u ON u.ID=g.UserId'; $sql.=' WHERE e.ExamTime BETWEEN ? AND ?'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $total=$this->db->querySingle($sql,[$begin_str,$end_str]); $sql='SELECT d.DepartmentName,u.Name,e.ExamName,e.ExamTime,e.Score,g.Score FROM grade g'; $sql.=' LEFT JOIN exam e ON e.ID=g.ExamId'; $sql.=' LEFT JOIN users u ON u.ID=g.UserId'; $sql.=' LEFT JOIN department d ON d.ID=u.DepartmentId'; $sql.=' WHERE e.ExamTime BETWEEN ? AND ?'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $sql.=' LIMIT ?,10'; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$begin_str,$end_str,$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++){ if(!$arr[$j][0]) $arr[$j][0]='全部部门'; $this->output($arr[$j]); } } } function exercise($opts){ if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $begin=(int)$opts['begin']; $end=(int)$opts['end']; $fileName=$name.'-练习数据-'.$this->time_range($begin,$end); if(isset($opts['download'])){ //header('Content-Disposition: attachment;filename="'.$fileName.'.csv"'); $this->set_filename($fileName.'.csv'); } if(!$this->db->exec('ATTACH DATABASE "exercise.db.php" AS "EX"')) return; $sql='SELECT COUNT(*) FROM EX.exercise e'; $sql.=' LEFT JOIN users u ON u.ID=e.uid'; $sql.=" WHERE e.time BETWEEN $begin AND $end"; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $total=$this->db->querySingle($sql); $h=['部门','身份','名字','时间','结果']; $this->output($h); $sql='SELECT d.DepartmentName,r.name,u.Name,datetime(e.Time,"unixepoch","localtime"),e.result FROM EX.exercise e'; $sql.=' LEFT JOIN users u ON u.ID=e.uid'; $sql.=' LEFT JOIN department d ON d.ID=u.DepartmentId'; $sql.=' LEFT JOIN role r ON r.ID=u.role'; $sql.=" WHERE e.time BETWEEN $begin AND $end"; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $sql.=' ORDER BY e.time ASC LIMIT ?,10'; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++){ if(!$arr[$j][4]) $arr[$j][4]='错误'; else $arr[$j][4]='正确'; $this->output($arr[$j]); } } } function set_filename($fileName){ $userAgent=$_SERVER['HTTP_USER_AGENT']; if($userAgent && strstr($userAgent,"Firefox")){ header('Content-Disposition: attachment;filename*="'."utf8''".urlencode($fileName).'"'); }else{ header('Content-Disposition: attachment;filename="'.urlencode($fileName).'"'); } } function study($opts){ if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $begin=(int)$opts['begin']; $end=(int)$opts['end']; $fileName=$name.'-学习时间-'.$this->time_range($begin,$end); if(isset($opts['download'])) //header('Content-Disposition: attachment;filename="'.$fileName.'.csv"'); $this->set_filename($fileName.'.csv'); $sql='SELECT COUNT(*) FROM studyRecord s'; $sql.=' LEFT JOIN users u ON u.ID=s.UserId'; $sql.=" WHERE s.Begin BETWEEN $begin AND $end"; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $total=$this->db->querySingle($sql); $h=['部门','身份','名字','时间','时长(秒)','类型']; $this->output($h); $sql='SELECT d.DepartmentName,r.name,u.Name,datetime(s.Begin,"unixepoch","localtime"),s.Duration,s.Type FROM studyRecord s'; $sql.=' LEFT JOIN users u ON u.ID=s.UserId'; $sql.=' LEFT JOIN department d ON d.ID=u.DepartmentId'; $sql.=' LEFT JOIN role r ON r.ID=u.role'; $sql.=" WHERE s.Begin BETWEEN $begin AND $end"; $sql.=" LIMIT ?,10"; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++){ if($arr[$j][5]==0) $arr[$j][5]='学习'; else $arr[$j][5]='练习'; $this->output($arr[$j]); } } } // 每一个学员学习时间要按学习类型分组加起来 function study2($opts){ if(!$this->db->exec('ATTACH DATABASE "exercise.db.php" AS "EX"')) return; if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $begin=(int)$opts['begin']; $end=(int)$opts['end']; $fileName=$name.'-学习时间-'.$this->time_range($begin,$end); if(isset($opts['download'])) $this->set_filename($fileName.'.csv'); $total=9999; $h=['部门','身份','名字','学习时间(秒)','练习时长(秒)','练习数量','练习正确数量','练习正确率']; $this->output($h); $sql='SELECT d.DepartmentName,r.name,u.Name,u.ID FROM users u'; $sql.=' LEFT JOIN department d ON d.ID=u.DepartmentId'; $sql.=' LEFT JOIN role r ON r.ID=u.role'; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' WHERE u.DepartmentId IN '.$deps; } $sql.=' LIMIT ?,10'; for($i=0;$i<$total;$i+=10){ $arr=$this->db->queryAll($sql,[$i]); if(!$arr) break; for($j=0;$j<count($arr);$j++){ $uid=array_pop($arr[$j]); $temp=$this->db->query("SELECT sum(-s.Duration*(s.Type-1)),sum(s.Duration*s.Type) FROM studyRecord s WHERE s.UserId=? AND s.Begin BETWEEN $begin AND $end",$uid); if($temp){ $arr[$j][]=(int)$temp[0]; $arr[$j][]=(int)$temp[1]; }else{ $arr[$j][]=0; $arr[$j][]=0; } $temp=$this->db->query('SELECT COUNT(*),SUM(e.result) FROM EX.exercise e WHERE e.uid=?',$uid); if($temp){ $arr[$j][]=(int)$temp[0]; $arr[$j][]=(int)$temp[1]; if($temp[0]>0){ $arr[$j][]=sprintf("%.2f",$temp[1]/$temp[0]); }else{ $arr[$j][]=0; } } $this->output($arr[$j]); } } } function get_libnames(){ $sql='SELECT Name FROM question_lib group by Name'; return $this->db->querySingleAll($sql); } function lib_error($opts){ $begin=(int)$opts['begin']; $end=(int)$opts['end']; if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $fileName=$name.'-高频错题-'.$this->time_range($begin,$end); if(isset($opts['download'])) $this->set_filename($fileName.'.csv'); $libs=$this->get_libnames(); if(!$this->db->exec('ATTACH DATABASE "exercise.db.php" AS "EX"')) return; $h=['题库','题型','题目','选项','答案','答题数','答题正确数量','正确率']; $this->output($h); $sql='CREATE TEMP VIEW stat AS SELECT qid,count(*) as count,sum(result) as result,sum(result)*1.0/count(*)*1.0 as accuracy FROM EX.exercise'; $sql.=' LEFT JOIN users u ON u.ID=uid'; $sql.=" WHERE time BETWEEN $begin AND $end"; if($department>0){ $deps=department_with_child_sql($this->db,$department); $sql.=' AND u.DepartmentId IN '.$deps; } $sql.=' GROUP BY qid'; $ret=$this->db->exec($sql); if(!$ret){ return; } $sql='SELECT q.LibName,q.Type,q.Question,q.Option,q.Answer,s.count,s.result,s.accuracy FROM stat s'; $sql.=' LEFT JOIN EX.question q ON q.ID=s.qid'; $sql.=' WHERE q.LibName=?'; $sql.=' AND s.count>=3'; $sql.=' ORDER BY s.accuracy ASC'; $sql.=' LIMIT 0,10'; for($i=0;$i<count($libs);$i++){ $temp=$this->db->queryAll($sql,$libs[$i]); if(!$temp) continue; for($j=0;$j<count($temp);$j++){ $this->output($temp[$j]); } } } //过关记录 function manmul_lib($opts){ $begin=(int)$opts['begin']; $end=(int)$opts['end']; if(isset($opts['department']) && $opts['department']>0){ $department=(int)$opts['department']; $name=$this->db->querySingle('SELECT DepartmentName FROM department WHERE ID=?',[$department]); if(!$name) return; }else{ $department=0; $name='全部部门'; } $fileName=$name.'-过关记录-'.$this->time_range($begin,$end); if(isset($opts['download'])) $this->set_filename($fileName.'.csv'); $libs=$this->get_libnames(); if(!$this->db->exec('ATTACH DATABASE "exercise.db.php" AS "EX"')) return; $h=['姓名','部门','过关记录','时间','难度系数']; $this->output($h); } } header('Content-Type: text/plain; charset=GB18030'); //header('Content-Type: application/octet-stream'); if(!isset($_GET['op'])) return; $op=$_GET['op']; if(!isset($_SESSION['AdminId'])) return; $ec=new ExportCSV(); if(!department_can_admin($ec->db,$_GET['department'],$_SESSION['AdminId'])) return; header('Cache-Control: max-age=0'); if($op=='user') $ec->user($_GET); else if($op=='exam') $ec->exam($_GET); else if($op=='grade') $ec->grade($_GET); else if($op=='exercise') $ec->exercise($_GET); else if($op=='study') $ec->study2($_GET); else if($op=='libe') $ec->lib_error($_GET); else if($op=='manmul') $ec->manmul_lib($_GET); ?>
一个模块的代码。附上结果图片php
下图为study方法中导出的练习数据,头部引入除过session都是封装了crud的db方法类,导出主要参考下面两个方法。sql
方法:session
function set_filename($fileName){ $userAgent=$_SERVER['HTTP_USER_AGENT']; if($userAgent && strstr($userAgent,"Firefox")){ header('Content-Disposition: attachment;filename*="'."utf8''".urlencode($fileName).'"'); }else{ header('Content-Disposition: attachment;filename="'.urlencode($fileName).'"'); } }
方法:app
function output(&$row){ for($i=0;$i<count($row);$i++){ $row[$i]=iconv('utf-8','gb18030',$row[$i]); } fputcsv($this->out,$row); }