<?php /** * 【调研中心-后台】20_已填写人员数据导出 * WriteListController.class.php * CreateBy:dj * Date:2017-03-08 */ namespace Frontend\Controller\Export; use Common\Service\AnswerService; use Common\Service\BaseinfoService; use Common\Service\QuestionService; use Common\Service\RecordService; use Org\Util\Emoji; class WriteListController extends \Common\Controller\Frontend\AbstractController { // 免登录 protected $_require_login = false; // 导出excel文件名 const QUESTIONNAIRE_XLS_FILE_NAME = '调研已填写人员数据'; /** @var BaseinfoService */ protected $_base_info_s; /** @var QuestionService */ protected $_question_s; /** @var RecordService */ protected $_record_s; /** @var AnswerService */ protected $_answer_s; // 前置操作 public function before_action($action = '') { if (parent::before_action($action) === false) { return false; } // 调研基本信息表 $this->_base_info_s = new BaseinfoService(); // 调研问题信息表 $this->_question_s = new QuestionService(); // 调研回答详情信息表 $this->_record_s = new RecordService(); // 调研回答用户记录表 $this->_answer_s = new AnswerService(); return true; } public function Index() { // 调研id $qu_id = trim(I('get.qu_id')); // 调研基本信息 $base_info = $this->_base_info_s->get($qu_id); // 查询调研题目信息列表 $question_list = $this->_question_s->list_by_conds(['qu_id' => $qu_id], null, ['q_order' => 'ASC']); // 数据格式化 $list = $this->format_data($base_info, $question_list, $qu_id); $this->export($base_info, $question_list, $list); return true; } /** * 获取数据列表并格式化 * * @param $base_info 调研基本信息 * @param $question_list 问题列表 * @param $qu_id 调研id * * @return array */ private function format_data($base_info, $question_list, $qu_id) { $list = []; // 调研填写记录信息 $answer_list = $this->_answer_s->list_by_conds(['qu_id' => $qu_id]); // 填写用户id集合 $uids = array_unique(array_filter(array_column($answer_list, 'uid'))); sort($uids); // 调研填写详情记录信息列表 $record_list = $this->_record_s->list_by_conds(['qu_id' => $qu_id]); $emoji = Emoji::instance(); // 查询用户列表,将用户列表转换成以用户uid为主键的二维数组 $user_list = $this->_base_info_s->getUser($uids); // 序号 $i = 1; foreach ($answer_list as $k => $v) { // 内部用户 if (!empty($v['uid'])) { // 内部用户 $u_type = '内部用户'; // 实名 if (BaseinfoService::REAL_NAME == $base_info['anonymous']) { // 用户信息 $user_data = $user_list[$v['uid']]; // 组织名称 $dp_name = ''; // 组织名称赋值 if (!empty($user_data['dpName'])) { $dp_name_array = array_column($user_data['dpName'], 'dpName'); $dp_name = implode(',', $dp_name_array); } $name = $user_data['memUsername']; $dpName = !empty($dp_name) ? $dp_name : ''; $jobName = !empty($user_data['memJob']) ? $user_data['memJob'] : ''; $roleName = !empty($user_data['memRole']) ? $user_data['memRole'] : ''; $mobile = !empty($user_data['memMobile']) ? $user_data['memMobile'] : ''; } elseif (BaseinfoService::ANONYMOUS == $base_info['anonymous']) { // 匿名 $name = '匿名用户' . $i; $dpName = ''; $jobName = ''; $roleName = ''; $mobile = ''; } } elseif (!empty($v['openid'])) { // 外部用户 $name = $v['username']; // 微信昵称 $dpName = ''; $jobName = ''; $roleName = ''; $mobile = ''; $u_type = '外部用户'; // 外部用户 } $list[$k] = [ $i, // 序号 $name, // 用户姓名 $dpName, // 组织名称 $jobName, // 岗位名称 $roleName, // 角色名称 $mobile, // 用户手机 $u_type, // 用户类型:内部用户/外部用户 rgmdate($v['created'], 'Y-m-d H:i') // 填写时间 ]; // 填写详情记录 $answer_data = []; // 填写详情记录赋值 foreach ($record_list as $_v) { if ($_v['a_id'] == $v['a_id']) { $answer_data[] = $_v; } } // 将此数组转换成以问题ID为主键的新数组 $answer_data = array_combine_by_key($answer_data, 'q_id'); // 遍历问题信息 foreach ($question_list as $_val) { // 问题的填写记录 $answer = $answer_data[$_val['qid']]; // 单选、复选、下拉选择、性别选择 if (in_array($_val['q_type'], QuestionService::OPTION_TYPE)) { // 问题内容 $option_arr = unserialize($_val['q_field']); // 回答内容 $answer_arr = unserialize($answer['answer']); $answer_option = array_column($answer_arr, 'option'); $answer_img = array_unique(array_filter(array_column($answer_arr, 'option_img'))); // 循环选项,看选项是否选中 for ($n = 0; $n < count($option_arr); $n++) { if (empty($answer['answer'])) { $list[$k][] = ''; // 未选中 continue; } // 如果选项中不包含图片,则只用 选项值就可以判断 if (empty($option_arr[$n]['option_img'])) { if (in_array($option_arr[$n]['option'], $answer_option)) { // 选中 $list[$k][] = '√'; } else { // 未选中 $list[$k][] = ''; } } else { if (in_array($option_arr[$n]['option'], $answer_option) && in_array($option_arr[$n]['option_img'], $answer_img) ) { // 选中 $list[$k][] = '√'; } else { // 未选中 $list[$k][] = ''; } } } // 是否包含其他选项(0:不包含,1:包含) if ($_val['q_other']) { // 包含其他选项 $list[$k][] = $answer['other']; } } else { // 上传图片和上传文件类型 if (in_array($_val['q_type'], QuestionService::FILE_TYPE)) { // 回答内容 $answer_arr = unserialize($answer['answer']); $answer_img = array_column($answer_arr, 'option_img'); $imgs = ''; // 循环选项,看选项是否选中 foreach ($answer_img as $v) { if (!empty($v)) { $imgs .= '\r\n' . imgUrl($v); } } // 图片集合 $list[$k][] = $imgs; } else { // 地址 if ($_val['q_type'] == 22) { $list[$k][] = $answer['answer'] . ' ' . $answer['other']; } else { $list[$k][] = $emoji->filter_emoji($answer['answer']); } } } } $i++; } return $list; } /** * 导出模板信息 * * @param array $base_info 问卷基本信息 * @param array $question_list 问题列表 * @param array $list 列表数据 */ private function export($base_info, $question_list, $list) { // 文件名 $fileName = self::QUESTIONNAIRE_XLS_FILE_NAME . date('_YmdHis'); $objExcelPhp = \Com\Excel::instance(); // 先确定是否有单选,复选,下拉选择题目 $is_option = 0; // 默认无 $num = 0; // 表格列数 foreach ($question_list as $v) { if (in_array($v['q_type'], QuestionService::OPTION_TYPE)) { // 如果问题是单选,复选,下拉类型 $is_option = 1; $option_arr = unserialize($v['q_field']); if ($v['q_other']) { // 包含其他选项 $num = $num + count($option_arr) + 1; // 一个选项占一列 } else { // 不包含其他选项 $num = $num + count($option_arr); // 一个选项占一列 } } else { // 问题类型为除单选,复选,下拉的其他类型 $num++; // 其他类型默认都只占一列 } } // 获取该导出数据所占列的最后一列标识 $start = 'A'; for ($i = 1; $i < $num + 8; $i++) { $start++; } // 组装表头第一行:标题 $objExcelPhp->getActiveSheet()->setCellValue('A1', '调研标题:' . $base_info['title']); $objExcelPhp->getActiveSheet()->mergeCells('A1:' . $start . '1'); // 表头字体加粗 if ($is_option) { // 如果包含选项类型 $objExcelPhp->getActiveSheet()->getStyle('A1:' . $start . '3')->getFont()->setBold(true); //$objExcelPhp->getActiveSheet()->getColumnDimension('A1:' . $start . '3')->setAutoSize(true); $objExcelPhp->getActiveSheet()->getStyle('A1:' . $start . '3')->getAlignment()->setHorizontal('center')->setVertical('center'); } else { // 如果不包含选项类型 $objExcelPhp->getActiveSheet()->getStyle('A1:' . $start . '2')->getFont()->setBold(true); $objExcelPhp->getActiveSheet()->getStyle('A1:' . $start . '2')->getAlignment()->setHorizontal('center')->setVertical('center'); } // 组装表头问题选项行 $start_column = 'A'; $start_arr = ['序号', '姓名', '组织', '岗位', '角色', '手机号', '用户类型', '填写时间']; foreach ($start_arr as $v) { if ($is_option) { // 给单元格赋值 $objExcelPhp->getActiveSheet()->setCellValue($start_column . '2', $v); // 合并行 $objExcelPhp->getActiveSheet()->mergeCells($start_column . '2:' . $start_column . '3'); } else { // 给单元格赋值 $objExcelPhp->getActiveSheet()->setCellValue($start_column . '2', $v); } $start_column++; } foreach ($question_list as $v) { if (in_array($v['q_type'], QuestionService::OPTION_TYPE)) { // 如果问题是单选,复选,下拉类型 $option_arr = unserialize($v['q_field']); // 组装其他选项 if ($v['q_other']) { // 包含其他选项 array_push($option_arr, ['option' => '其他']); } $kai = $start_column; // 开始合并的列标识 for ($i = 1; $i <= count($option_arr); $i++) { if ($i == count($option_arr)) { $objExcelPhp->getActiveSheet()->mergeCells($kai . '2:' . $start_column . '2'); } $objExcelPhp->getActiveSheet()->setCellValue($start_column . '3', $option_arr[$i - 1]['option']); $start_column++; } $objExcelPhp->getActiveSheet()->setCellValue($kai . '2', $v['q_title']); } else { // 问题类型为除单选,复选,下拉的其他类型 if ($is_option) { // 给单元格赋值 $objExcelPhp->getActiveSheet()->setCellValue($start_column . '2', $v['q_title']); // 合并行 $objExcelPhp->getActiveSheet()->mergeCells($start_column . '2:' . $start_column . '3'); } else { // 给单元格赋值 $objExcelPhp->getActiveSheet()->setCellValue($start_column . '2', $v['q_title']); } $start_column++; } } // 循环表格体赋值(因为封装方法是从第二行开始赋值的,此处将赋值方法单独提出来处理) if ($is_option) { $n = 4; // 如果包含选项类型,从第四行开始赋值 } else { $n = 3; // 如果不包含选项类型,从第三行开始赋值 } foreach ($list as $_row) { $start = 'A'; for ($i = 0; $i < count($_row); $i++) { $_column = $start++; $objExcelPhp->getActiveSheet()->setCellValueExplicit($_column . $n, $_row[$i], $this->__set_data_type($_row[$i])); $objExcelPhp->getActiveSheet() ->getStyle($_column . $n) ->getAlignment() ->setWrapText(true) ->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); } $n++; } $objExcelPhp->make_excel_download($fileName, null, null, []); } private function __set_data_type($str) { if (is_numeric($str)) { if (false !== strpos($str, '.')) { return 'b'; } elseif (!isset($str{3})) { return 'n'; } else { return 'str'; } } else { return 'str'; } } }