From 0f4208a2cd5356d97d7a8d6f96466bdb65ec2f93 Mon Sep 17 00:00:00 2001 From: vilson <545522390@qq.com> Date: Thu, 11 Jul 2019 17:08:31 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E7=BB=84=E7=BB=87=E6=88=90=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: vilson <545522390@qq.com> --- application/common/Model/DepartmentMember.php | 114 ++++++++++++++++-- application/common/Model/Member.php | 36 ++++-- application/common/Model/MemberAccount.php | 39 +++--- application/common/Model/Project.php | 1 + .../project/controller/DepartmentMember.php | 39 +++++- application/project/controller/Index.php | 22 +++- data/template/importMember.xlsx | Bin 0 -> 9198 bytes 7 files changed, 208 insertions(+), 43 deletions(-) create mode 100644 data/template/importMember.xlsx diff --git a/application/common/Model/DepartmentMember.php b/application/common/Model/DepartmentMember.php index d69c3db..ded76e1 100644 --- a/application/common/Model/DepartmentMember.php +++ b/application/common/Model/DepartmentMember.php @@ -3,6 +3,12 @@ namespace app\common\Model; +use Exception; +use service\RandomService; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\exception\DbException; + /** * 部门成员 * Class ProjectMember @@ -18,9 +24,9 @@ class DepartmentMember extends CommonModel * @param int $isOwner 是否拥有者 * @param int $isPrincipal 是否负责人 * @return DepartmentMember|MemberAccount - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public function inviteMember($accountCode, $departmentCode = '', $isOwner = 0, $isPrincipal = 0) { @@ -28,11 +34,11 @@ class DepartmentMember extends CommonModel if ($departmentCode) { $department = Department::where(['code' => $departmentCode])->find(); if (!$department) { - throw new \Exception('该部门不存在', 1); + throw new Exception('该部门不存在', 1); } $hasJoined = self::where(['account_code' => $accountCode, 'department_code' => $departmentCode])->find(); if ($hasJoined) { - throw new \Exception('已加入该部门', 2); + throw new Exception('已加入该部门', 2); } $data = [ 'code' => createUniqueCode('departmentMember'), @@ -53,8 +59,8 @@ class DepartmentMember extends CommonModel } else { try { $result = MemberAccount::inviteMember($accountCode, $orgCode); - } catch (\Exception $e) { - throw new \Exception($e->getMessage(), 3); + } catch (Exception $e) { + throw new Exception($e->getMessage(), 3); } return $result; } @@ -64,20 +70,20 @@ class DepartmentMember extends CommonModel * @param $accountCode * @param $departmentCode * @return bool - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public function removeMember($accountCode, $departmentCode) { $orgCode = getCurrentOrganizationCode(); $department = Department::where(['code' => $departmentCode])->find(); if (!$department) { - throw new \Exception('该部门不存在', 1); + throw new Exception('该部门不存在', 1); } $hasJoined = self::where(['account_code' => $accountCode, 'department_code' => $departmentCode])->find(); if (!$hasJoined) { - throw new \Exception('尚未加入该部门', 2); + throw new Exception('尚未加入该部门', 2); } $result = $hasJoined->delete(); $department_codes = self::where(['account_code' => $accountCode, 'organization_code' => $orgCode])->column('department_code'); @@ -86,4 +92,88 @@ class DepartmentMember extends CommonModel MemberAccount::update(['department_code' => $department_codes], ['code' => $accountCode]); return $result; } + + /** + * 导入成员 + * @param \think\File $file + * @return bool + * @throws Exception + */ + public function uploadFile(\think\File $file) + { + try { + $data = importExcel($file->getInfo()['tmp_name']); + } catch (Exception $e) { + return error('201', $e->getMessage()); + } + $count = 0; + if ($data) { + $organizationCode = getCurrentOrganizationCode(); + foreach ($data as $key => $item) { + if ($key > 3) { + $name = trim($item['A']); + $email = trim($item['B']); + $departments = trim($item['C']); + $position = trim($item['D']); + $mobile = trim($item['E']); + $password = trim($item['F']); + $description = trim($item['G']); + $member = Member::where(['email' => $email])->find(); + if (!$member) { + //注册新账号 + $memberData = [ + 'email' => $email, + 'name' => $name, + 'account' => RandomService::alnumLowercase(), + 'avatar' => 'https://static.vilson.xyz/cover.png', + 'status' => 1, + 'code' => createUniqueCode('member'), + 'password' => $password ? md5($password) : '', +// 'mobile' => $mobile, + ]; + try { + $result = Member::createMember($memberData); + } catch (Exception $e) { + return error(1, $e->getMessage()); + } + $member = Member::get($result->id); + $memberAccount = MemberAccount::inviteMember($member['code'], $organizationCode, $position, $mobile, '', $description); + if (!isError($memberAccount)) { + $count++; + } + } else { + $memberAccount = MemberAccount::where(['member_code' => $member['code'], 'organization_code' => $organizationCode])->find(); + } + if ($departments) { + $departmentList = explode(';', $departments); + if ($departmentList) { + foreach ($departmentList as $departmentItems) { + $departmentNames = explode('/', $departmentItems); + if ($departmentNames) { + $department = null; + $pcode = ''; + foreach ($departmentNames as $key => $departmentName) { + $department = Department::where(['name' => $departmentNames, 'pcode' => $pcode, 'organization_code' => $organizationCode])->find(); + if (!$department) { + break; + } + $pcode = $department['code']; + } + if ($department) { + try { + $this->inviteMember($memberAccount['code'], $department['code']); + } catch (Exception $e) { + return error(2, $e->getMessage()); + } + } + } + } + } + } + } + + } + } + return $count; + } } diff --git a/application/common/Model/Member.php b/application/common/Model/Member.php index a27d908..7767993 100644 --- a/application/common/Model/Member.php +++ b/application/common/Model/Member.php @@ -2,12 +2,18 @@ namespace app\common\Model; +use Exception; use PDOStatement; use service\JwtService; use service\NodeService; use service\RandomService; use think\Db; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\exception\DbException; +use think\exception\PDOException; use think\File; +use think\Model; class Member extends CommonModel { @@ -23,7 +29,17 @@ class Member extends CommonModel $list = MemberAccount::where(['member_code' => $member['code']])->order('id asc')->select()->toArray(); $organizationList = []; if ($list) { - foreach ($list as $item) { + foreach ($list as &$item) { + $departments = ''; + $departmentCodes = $item['department_code']; + if ($departmentCodes) { + $departmentCodes = explode(',', $departmentCodes); + foreach ($departmentCodes as $departmentCode) { + $department = Department::where(['code' => $departmentCode])->field('name')->find(); + $departments .= "{$department['name']} "; + } + } + $item['department'] = $departments; $organization = Organization::where(['code' => $item['organization_code']])->find(); if ($organization) { $organizationList[] = $organization; @@ -51,9 +67,9 @@ class Member extends CommonModel /** * @param $memberData * @return Member - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public static function createMember($memberData) { @@ -128,10 +144,10 @@ class Member extends CommonModel /** * 钉钉登录 * @param $userInfo - * @return Member|array|PDOStatement|string|\think\Model|null - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @return Member|array|PDOStatement|string|Model|null + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public static function dingtalkLogin($userInfo) { @@ -186,8 +202,8 @@ class Member extends CommonModel * @param File $file * @return array|bool * @throws \think\Exception - * @throws \think\exception\PDOException - * @throws \Exception + * @throws PDOException + * @throws Exception */ public function uploadImg(File $file) { diff --git a/application/common/Model/MemberAccount.php b/application/common/Model/MemberAccount.php index 5fc93de..642e140 100644 --- a/application/common/Model/MemberAccount.php +++ b/application/common/Model/MemberAccount.php @@ -2,8 +2,13 @@ namespace app\common\Model; +use Exception; use service\NodeService; use think\Db; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\exception\DbException; +use think\exception\PDOException; use think\File; class MemberAccount extends CommonModel @@ -13,9 +18,9 @@ class MemberAccount extends CommonModel /** * 获取当前用户菜单 - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public static function getAuthMenuList() { @@ -29,12 +34,16 @@ class MemberAccount extends CommonModel * 邀请成员 * @param $memberCode * @param $organizationCode + * @param string $position + * @param string $mobile + * @param string $department + * @param string $description * @return MemberAccount - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException */ - public static function inviteMember($memberCode, $organizationCode) + public static function inviteMember($memberCode, $organizationCode, $position = '', $mobile = '', $department = '', $description = '') { $hasJoined = MemberAccount::where(['member_code' => $memberCode, 'organization_code' => $organizationCode])->find(); if ($hasJoined) { @@ -50,8 +59,9 @@ class MemberAccount extends CommonModel $authId = $auth['id'];//权限id } $data = [ - 'position' => '资深工程师', - 'department' => '某某公司-某某某事业群-某某平台部-某某技术部', + 'position' => $position, + 'department' => $department ?? '某某公司-某某某事业群-某某平台部-某某技术部', + 'description' => $description ?? '', 'code' => createUniqueCode('memberAccount'), 'member_code' => $memberCode, 'organization_code' => $organizationCode, @@ -60,6 +70,7 @@ class MemberAccount extends CommonModel 'status' => 1, 'create_time' => nowTime(), 'name' => $memberDate['name'], + 'mobile' => $mobile, 'email' => $memberDate['email'], ]; return MemberAccount::create($data); @@ -69,8 +80,8 @@ class MemberAccount extends CommonModel * @param File $file * @return array|bool * @throws \think\Exception - * @throws \think\exception\PDOException - * @throws \Exception + * @throws PDOException + * @throws Exception */ public function uploadImg(File $file) { @@ -100,7 +111,7 @@ class MemberAccount extends CommonModel /** * @param $accountCode * @return bool - * @throws \Exception + * @throws Exception */ public function del($accountCode) { @@ -116,9 +127,9 @@ class MemberAccount extends CommonModel DepartmentMember::where(['account_code' => $accountCode, 'organization_code' => $orgCode])->delete(); } Db::commit(); - } catch (\Exception $e) { + } catch (Exception $e) { Db::rollback(); - throw new \Exception($e->getMessage(), 201); + throw new Exception($e->getMessage(), 201); } return true; } diff --git a/application/common/Model/Project.php b/application/common/Model/Project.php index 12d6856..9f9c034 100644 --- a/application/common/Model/Project.php +++ b/application/common/Model/Project.php @@ -65,6 +65,7 @@ class Project extends CommonModel 'name' => $name, 'description' => $description, 'organization_code' => $orgCode, + 'task_board_theme' => 'simple', 'cover' => FileService::getFilePrefix() . 'static/image/default/project-cover.png' ]; $result = self::create($project); diff --git a/application/project/controller/DepartmentMember.php b/application/project/controller/DepartmentMember.php index 1ad6414..91315c9 100644 --- a/application/project/controller/DepartmentMember.php +++ b/application/project/controller/DepartmentMember.php @@ -5,7 +5,12 @@ namespace app\project\controller; use app\common\Model\Member; use app\common\Model\MemberAccount; use controller\BasicApi; +use Exception; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\exception\DbException; use think\facade\Request; +use think\response\Download; /** * 部门成员 @@ -21,7 +26,7 @@ class DepartmentMember extends BasicApi } /** - * @throws \think\exception\DbException + * @throws DbException */ public function index() { @@ -46,9 +51,9 @@ class DepartmentMember extends BasicApi /** * 邀请成员查询 - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException + * @throws DataNotFoundException + * @throws ModelNotFoundException + * @throws DbException */ public function searchInviteMember() { @@ -119,7 +124,7 @@ class DepartmentMember extends BasicApi } try { $this->model->inviteMember($data['accountCode'], $data['departmentCode']); - } catch (\Exception $e) { + } catch (Exception $e) { $this->error($e->getMessage(), $e->getCode());; } $this->success(''); @@ -136,9 +141,31 @@ class DepartmentMember extends BasicApi } try { $this->model->removeMember($data['accountCode'], $data['departmentCode']); - } catch (\Exception $e) { + } catch (Exception $e) { $this->error($e->getMessage(), $e->getCode());; } $this->success(''); } + + /** + * 下载导入成员模板 + * @return Download + */ + public function _downloadTemplate() + { + return download(env('root_path') . 'data/template/importMember.xlsx', '批量导入成员模板.xlsx'); + } + + /** + * 上传文件 + */ + public function uploadFile() + { + $count = $this->model->uploadFile(Request::file('file')); + if (isError($count)) { + $this->error($count['msg']); + } + $this->success('', $count); + } + } diff --git a/application/project/controller/Index.php b/application/project/controller/Index.php index 6b08d98..7e59be6 100644 --- a/application/project/controller/Index.php +++ b/application/project/controller/Index.php @@ -3,6 +3,7 @@ namespace app\project\controller; use app\common\Model\CommonModel; +use app\common\Model\Department; use app\common\Model\Member; use app\common\Model\MemberAccount; use app\common\Model\Notify; @@ -58,6 +59,18 @@ class Index extends BasicApi $member = getCurrentMember(); $memberAccount = MemberAccount::where(['member_code' => $member['code'], 'organization_code' => $organizationCode])->find(); $member = Member::where(['account' => $member['account']])->order('id asc')->find()->toArray(); + + $departments = ''; + $departmentCodes = $memberAccount['department_code']; + if ($departmentCodes) { + $departmentCodes = explode(',', $departmentCodes); + foreach ($departmentCodes as $departmentCode) { + $department = Department::where(['code' => $departmentCode])->field('name')->find(); + $departments .= "{$department['name']} "; + } + } + $member['position'] = $memberAccount['position']; + $member['department'] = $departments; $member['account_id'] = $memberAccount['id']; $member['is_owner'] = $memberAccount['is_owner']; $member['authorize'] = $memberAccount['authorize']; @@ -66,7 +79,7 @@ class Index extends BasicApi setCurrentOrganizationCode($organizationCode); $list = MemberAccount::getAuthMenuList(); - $this->success('', $list); + $this->success('', ['menuList' => $list, 'member' => $member]); } $this->error('请选择组织'); } @@ -101,6 +114,10 @@ class Index extends BasicApi $params = Request::only('mobile,mail,idcard,name,realname,avatar,id'); $memberModel = new Member(); $result = $memberModel->_edit($params, ['id' => Request::post('id')]); + if (isset($params['avatar'])) { + $member = Member::get($params['id']); + MemberAccount::update(['avatar' => $params['avatar']], ['member_code' => $member['code']]); + } if ($result) { $this->success('基本信息更新成功'); } @@ -114,6 +131,9 @@ class Index extends BasicApi */ public function editPassword() { + var_dump(11); + die; + $memberModel = new Member(); $params = Request::only('password,newPassword,confirmPassword,id'); $member = $memberModel->field('password')->get($params['id'])->toArray(); diff --git a/data/template/importMember.xlsx b/data/template/importMember.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8aae9ef5977bda23b6147b85f63fb1501ab02c3b GIT binary patch literal 9198 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 literal 0 HcmV?d00001 From 4cf5f89c3cf10c2356f3a6f5ba19daca1021b81a Mon Sep 17 00:00:00 2001 From: vilson <545522390@qq.com> Date: Thu, 11 Jul 2019 17:10:01 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E7=BB=84=E7=BB=87=E6=88=90=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: vilson <545522390@qq.com> --- application/common.php | 317 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) diff --git a/application/common.php b/application/common.php index 6c146e1..d77f951 100644 --- a/application/common.php +++ b/application/common.php @@ -1,5 +1,15 @@ canRead($file)) { + /** @var Xls $objRead */ + $objRead = IOFactory::createReader('Xls'); + + if (!$objRead->canRead($file)) { + throw new \Exception('只支持导入Excel文件!'); + } + } + + /* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */ + empty($options) && $objRead->setReadDataOnly(true); + /* 建立excel对象 */ + $obj = $objRead->load($file); + /* 获取指定的sheet表 */ + $currSheet = $obj->getSheet($sheet); + + if (isset($options['mergeCells'])) { + /* 读取合并行列 */ + $options['mergeCells'] = $currSheet->getMergeCells(); + } + + if (0 == $columnCnt) { + /* 取得最大的列号 */ + $columnH = $currSheet->getHighestColumn(); + /* 兼容原逻辑,循环时使用的是小于等于 */ + $columnCnt = Coordinate::columnIndexFromString($columnH); + } + + /* 获取总行数 */ + $rowCnt = $currSheet->getHighestRow(); + $data = []; + + /* 读取内容 */ + for ($_row = 1; $_row <= $rowCnt; $_row++) { + $isNull = true; + + for ($_column = 1; $_column <= $columnCnt; $_column++) { + $cellName = Coordinate::stringFromColumnIndex($_column); + $cellId = $cellName . $_row; + $cell = $currSheet->getCell($cellId); + + if (isset($options['format'])) { + /* 获取格式 */ + $format = $cell->getStyle()->getNumberFormat()->getFormatCode(); + /* 记录格式 */ + $options['format'][$_row][$cellName] = $format; + } + + if (isset($options['formula'])) { + /* 获取公式,公式均为=号开头数据 */ + $formula = $currSheet->getCell($cellId)->getValue(); + + if (0 === strpos($formula, '=')) { + $options['formula'][$cellName . $_row] = $formula; + } + } + + if (isset($format) && 'm/d/yyyy' == $format) { + /* 日期格式翻转处理 */ + $cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd'); + } + + $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue()); + + if (!empty($data[$_row][$cellName])) { + $isNull = false; + } + } + + /* 判断是否整行数据为空,是的话删除该行数据 */ + if ($isNull) { + unset($data[$_row]); + } + } + + return $data; + } catch (\Exception $e) { + throw $e; + } +} + +/** + * Excel导出,TODO 可继续优化 + * + * @param array $datas 导出数据,格式['A1' => 'XXXX公司报表', 'B1' => '序号'] + * @param string $fileName 导出文件名称 + * @param array $options 操作选项,例如: + * bool print 设置打印格式 + * string freezePane 锁定行数,例如表头为第一行,则锁定表头输入A2 + * array setARGB 设置背景色,例如['A1', 'C1'] + * array setWidth 设置宽度,例如['A' => 30, 'C' => 20] + * bool setBorder 设置单元格边框 + * array mergeCells 设置合并单元格,例如['A1:J1' => 'A1:J1'] + * array formula 设置公式,例如['F2' => '=IF(D2>0,E42/D2,0)'] + * array format 设置格式,整列设置,例如['A' => 'General'] + * array alignCenter 设置居中样式,例如['A1', 'A2'] + * array bold 设置加粗样式,例如['A1', 'A2'] + * string savePath 保存路径,设置后则文件保存到服务器,不通过浏览器下载 + * @return bool + */ +function exportExcel(array $datas, string $fileName = '', array $options = []): bool +{ + try { + if (empty($datas)) { + return false; + } + + set_time_limit(0); + /** @var Spreadsheet $objSpreadsheet */ + $objSpreadsheet = app(Spreadsheet::class); + /* 设置默认文字居左,上下居中 */ + $styleArray = [ + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_LEFT, + 'vertical' => Alignment::VERTICAL_CENTER, + ], + ]; + $objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray); + /* 设置Excel Sheet */ + $activeSheet = $objSpreadsheet->setActiveSheetIndex(0); + + /* 打印设置 */ + if (isset($options['print']) && $options['print']) { + /* 设置打印为A4效果 */ + $activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4); + /* 设置打印时边距 */ + $pValue = 1 / 2.54; + $activeSheet->getPageMargins()->setTop($pValue / 2); + $activeSheet->getPageMargins()->setBottom($pValue * 2); + $activeSheet->getPageMargins()->setLeft($pValue / 2); + $activeSheet->getPageMargins()->setRight($pValue / 2); + } + + /* 行数据处理 */ + foreach ($datas as $sKey => $sItem) { + /* 默认文本格式 */ + $pDataType = DataType::TYPE_STRING; + + /* 设置单元格格式 */ + if (isset($options['format']) && !empty($options['format'])) { + $colRow = Coordinate::coordinateFromString($sKey); + + /* 存在该列格式并且有特殊格式 */ + if (isset($options['format'][$colRow[0]]) && + NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) { + $activeSheet->getStyle($sKey)->getNumberFormat() + ->setFormatCode($options['format'][$colRow[0]]); + + if (false !== strpos($options['format'][$colRow[0]], '0.00') && + is_numeric(str_replace(['¥', ','], '', $sItem))) { + /* 数字格式转换为数字单元格 */ + $pDataType = DataType::TYPE_NUMERIC; + $sItem = str_replace(['¥', ','], '', $sItem); + } + } elseif (is_int($sItem)) { + $pDataType = DataType::TYPE_NUMERIC; + } + } + + $activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType); + + /* 存在:形式的合并行列,列入A1:B2,则对应合并 */ + if (false !== strstr($sKey, ":")) { + $options['mergeCells'][$sKey] = $sKey; + } + } + + unset($datas); + + /* 设置锁定行 */ + if (isset($options['freezePane']) && !empty($options['freezePane'])) { + $activeSheet->freezePane($options['freezePane']); + unset($options['freezePane']); + } + + /* 设置宽度 */ + if (isset($options['setWidth']) && !empty($options['setWidth'])) { + foreach ($options['setWidth'] as $swKey => $swItem) { + $activeSheet->getColumnDimension($swKey)->setWidth($swItem); + } + + unset($options['setWidth']); + } + + /* 设置背景色 */ + if (isset($options['setARGB']) && !empty($options['setARGB'])) { + foreach ($options['setARGB'] as $sItem) { + $activeSheet->getStyle($sItem) + ->getFill()->setFillType(Fill::FILL_SOLID) + ->getStartColor()->setARGB(Color::COLOR_YELLOW); + } + + unset($options['setARGB']); + } + + /* 设置公式 */ + if (isset($options['formula']) && !empty($options['formula'])) { + foreach ($options['formula'] as $fKey => $fItem) { + $activeSheet->setCellValue($fKey, $fItem); + } + + unset($options['formula']); + } + + /* 合并行列处理 */ + if (isset($options['mergeCells']) && !empty($options['mergeCells'])) { + $activeSheet->setMergeCells($options['mergeCells']); + unset($options['mergeCells']); + } + + /* 设置居中 */ + if (isset($options['alignCenter']) && !empty($options['alignCenter'])) { + $styleArray = [ + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER, + ], + ]; + + foreach ($options['alignCenter'] as $acItem) { + $activeSheet->getStyle($acItem)->applyFromArray($styleArray); + } + + unset($options['alignCenter']); + } + + /* 设置加粗 */ + if (isset($options['bold']) && !empty($options['bold'])) { + foreach ($options['bold'] as $bItem) { + $activeSheet->getStyle($bItem)->getFont()->setBold(true); + } + + unset($options['bold']); + } + + /* 设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列 */ + if (isset($options['setBorder']) && $options['setBorder']) { + $border = [ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => Border::BORDER_THIN, // 设置border样式 + 'color' => ['argb' => 'FF000000'], // 设置border颜色 + ], + ], + ]; + $setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow(); + $activeSheet->getStyle($setBorder)->applyFromArray($border); + unset($options['setBorder']); + } + + $fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx'); + + if (!isset($options['savePath'])) { + /* 直接导出Excel,无需保存到本地,输出07Excel文件 */ + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header( + "Content-Disposition:attachment;filename=" . iconv( + "utf-8", "GB2312//TRANSLIT", $fileName + ) + ); + header('Cache-Control: max-age=0');//禁止缓存 + $savePath = 'php://output'; + } else { + $savePath = $options['savePath']; + } + + ob_clean(); + ob_start(); + $objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx'); + $objWriter->save($savePath); + /* 释放内存 */ + $objSpreadsheet->disconnectWorksheets(); + unset($objSpreadsheet); + ob_end_flush(); + + return true; + } catch (Exception $e) { + return false; + } +} + /** * UTF8字符串加密 * @param string $string From 2ea78c0d9953fd74e529515a2c00942f7c66ffd4 Mon Sep 17 00:00:00 2001 From: vilson <545522390@qq.com> Date: Thu, 11 Jul 2019 17:10:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=87=B32.7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: vilson <545522390@qq.com> --- config/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app.php b/config/app.php index e7a2f35..7ba0810 100644 --- a/config/app.php +++ b/config/app.php @@ -6,7 +6,7 @@ return [ // 应用名称 'app_name' => 'pearProject', // 应用版本 - 'app_version' => '2.6.2', + 'app_version' => '2.7.0', // 应用地址 'app_host' => '', // 应用调试模式