本篇文章给大家介绍一下使用phpspreadsheet导入导出excel的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
php对excel导入&导出操作最近公司要做报表功能,各种财务报表、工资报表、考勤报表等,复杂程度让人头大,于是特地封装适用各大场景的导入&导出操作,希望各界大神支出不足之处,以便小弟继续完善。
phpspreadsheet 引入由于phpexcel早就停止更新维护,所以适用phpspreadsheet。不知道如何通过composer拉取项目包的同学,可以查看composer学习一文。引入方法:
composer require phpoffice/phpspreadsheet
引入命名空间由于本人项目中需要居中、背景、单元格格式等各种操作,所以引入较多,大家使用的时候,可以根据自己实际需要引入。
use phpoffice\phpspreadsheet\reader\xlsx;use phpoffice\phpspreadsheet\reader\xls;use phpoffice\phpspreadsheet\iofactory;use phpoffice\phpspreadsheet\cell\coordinate;use phpoffice\phpspreadsheet\spreadsheet;use phpoffice\phpspreadsheet\worksheet\pagesetup;use phpoffice\phpspreadsheet\cell\datatype;use phpoffice\phpspreadsheet\style\fill;use phpoffice\phpspreadsheet\style\color;use phpoffice\phpspreadsheet\style\alignment;use phpoffice\phpspreadsheet\style\border;use phpoffice\phpspreadsheet\style\numberformat;
excel导入操作(importexcel)除了单纯的处理excel数据外,还可以将excel中的合并项、公式项、单元格格式提取,提取后可根据业务需求做对应处理后存储起来,以便后续的各种操作。
/** * 使用phpexecl导入 * * @param string $file 文件地址 * @param int $sheet 工作表sheet(传0则获取第一个sheet) * @param int $columncnt 列数(传0则自动获取最大列) * @param array $options 操作选项 * array mergecells 合并单元格数组 * array formula 公式数组 * array format 单元格格式数组 * * @return array * @throws exception */function importexecl(string $file = '', int $sheet = 0, int $columncnt = 0, &$options = []){ try { /* 转码 */ $file = iconv("utf-8", "gb2312", $file); if (empty($file) or !file_exists($file)) { throw new \exception('文件不存在!'); } /** @var xlsx $objread */ $objread = iofactory::createreader('xlsx'); if (!$objread->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做各种不同的配置,例如打印样式、锁定行、背景色、宽度等。
excel导出操作(exportexcel)/** * 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 保存路径,设置后则文件保存到服务器,不通过浏览器下载 */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; }}
推荐学习:php视频教程
以上就是如何使用phpspreadsheet导入导出excel的详细内容。