123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <?php
- /**
- * lemocms
- * ============================================================================
- * 版权所有 2018-2027 lemocms,并保留所有权利。
- * 网站地址: https://www.lemocms.com
- * ----------------------------------------------------------------------------
- * 采用最新Thinkphp6实现
- * ============================================================================
- * Author: yuege
- * Date: 2019/9/26
- */
- namespace lemo\helper;
- use Exception;
- use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
- use PhpOffice\PhpSpreadsheet\Spreadsheet;
- use PhpOffice\PhpSpreadsheet\Writer\Html;
- use PhpOffice\PhpSpreadsheet\Writer\Xls;
- use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
- use PhpOffice\PhpSpreadsheet\Writer\Csv;
- class ExcelHelper
- {
- /**
- * 导出Excel
- *
- * @param array $list
- * @param array $header
- * @param string $filename
- * @param string $title
- * @return bool
- * @throws \PhpOffice\PhpSpreadsheet\Exception
- * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
- */
- public static function exportData($data = [], $header = [], $filename = '', $suffix = '.xlsx')
- {
- $filename .= "_" . date("Y_m_d", time()) . $suffix;
- $spreadsheet = new Spreadsheet();
- $objPHPExcel = $spreadsheet->getActiveSheet();
- $key = ord("A"); // 设置表头
- foreach ($header as $v) {
- $colum = chr($key);
- $objPHPExcel->setCellValue($colum . '1', $v);
- $key += 1;
- }
- $column = 2;
- foreach ($data as $key => $rows) {
- // 行写入
- $span = ord("A");
- foreach ($rows as $keyName => $value) {
- // 列写入
- $objPHPExcel->setCellValue(chr($span) . $column, $value);
- $span++;
- }
- $column++;
- }
- //$fileName = iconv("utf-8", "gbk//IGNORE", $fileName); // 重命名表(UTF8编码不需要这一步)
- header('Content-Type: application/vnd.ms-excel');
- header('Content-Disposition: attachment;filename="' . $filename . $suffix);
- header('Cache-Control: max-age=0');
- $writer = new Xlsx($spreadsheet);
- $writer->save('php://output');
- //删除清空:
- $spreadsheet->disconnectWorksheets();
- unset($spreadsheet);
- exit;
- }
- /**
- * 导出的另外一种形式(不建议使用)
- *
- * @param array $list
- * @param array $header
- * @param string $filename
- * @return bool
- */
- public static function exportCsvData($list = [], $header = [], $filename = '')
- {
- if (!is_array($list) || !is_array($header)) {
- return false;
- }
- // 清除之前的错误输出
- ob_end_clean();
- ob_start();
- !$filename && $filename = time();
- $html = "\xEF\xBB\xBF";
- foreach ($header as $k => $v) {
- $html .= $v[0] . "\t ,";
- }
- $html .= "\n";
- if (!empty($list)) {
- $info = [];
- $size = ceil(count($list) / 500);
- for ($i = 0; $i < $size; $i++) {
- $buffer = array_slice($list, $i * 500, 500);
- foreach ($buffer as $k => $row) {
- $data = [];
- foreach ($header as $key => $value) {
- // 解析字段
- $realData = self::formatting($header[$key], trim(self::formattingField($row, $value[1])), $row);
- $data[] = str_replace(PHP_EOL, '', $realData);
- }
- $info[] = implode("\t ,", $data) . "\t ,";
- unset($data, $buffer[$k]);
- }
- }
- $html .= implode("\n", $info);
- }
- header("Content-type:text/csv");
- header("Content-Disposition:attachment; filename={$filename}.csv");
- echo $html;
- exit();
- }
- /**
- * 导入
- *
- * @param $filePath
- * @param int $startRow
- * @return array|mixed
- * @throws Exception
- * @throws \PhpOffice\PhpSpreadsheet\Exception
- * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
- */
- public static function import($filePath, $startRow = 1)
- {
- $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
- $reader->setReadDataOnly(true);
- if (!$reader->canRead($filePath)) {
- $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
- // setReadDataOnly Set read data only 只读单元格的数据,不格式化 e.g. 读时间会变成一个数据等
- $reader->setReadDataOnly(true);
- if (!$reader->canRead($filePath)) {
- throw new Exception('不能读取Excel');
- }
- }
- $spreadsheet = $reader->load($filePath);
- $sheetCount = $spreadsheet->getSheetCount();// 获取sheet的数量
- // 获取所有的sheet表格数据
- $excleDatas = [];
- $emptyRowNum = 0;
- for ($i = 0; $i < $sheetCount; $i++) {
- $currentSheet = $spreadsheet->getSheet($i); // 读取excel文件中的第一个工作表
- $allColumn = $currentSheet->getHighestColumn(); // 取得最大的列号
- $allColumn = Coordinate::columnIndexFromString($allColumn); // 由列名转为列数('AB'->28)
- $allRow = $currentSheet->getHighestRow(); // 取得一共有多少行
- $arr = [];
- for ($currentRow = $startRow; $currentRow <= $allRow; $currentRow++) {
- // 从第1列开始输出
- for ($currentColumn = 1; $currentColumn <= $allColumn; $currentColumn++) {
- $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
- $arr[$currentRow][] = trim($val);
- }
- // $arr[$currentRow] = array_filter($arr[$currentRow]);
- // 统计连续空行
- if (empty($arr[$currentRow]) && $emptyRowNum <= 50) {
- $emptyRowNum++;
- } else {
- $emptyRowNum = 0;
- }
- // 防止坑队友的同事在excel里面弄出很多的空行,陷入很漫长的循环中,设置如果连续超过50个空行就退出循环,返回结果
- // 连续50行数据为空,不再读取后面行的数据,防止读满内存
- if ($emptyRowNum > 50) {
- break;
- }
- }
- $excleDatas[$i] = $arr; // 多个sheet的数组的集合
- }
- // 这里我只需要用到第一个sheet的数据,所以只返回了第一个sheet的数据
- $returnData = $excleDatas ? array_shift($excleDatas) : [];
- // 第一行数据就是空的,为了保留其原始数据,第一行数据就不做array_fiter操作;
- $returnData = $returnData && isset($returnData[$startRow]) && !empty($returnData[$startRow]) ? array_filter($returnData) : $returnData;
- return $returnData;
- }
- /**
- * 格式化内容
- *
- * @param array $array 头部规则
- * @return false|mixed|null|string 内容值
- */
- protected static function formatting(array $array, $value, $row)
- {
- !isset($array[2]) && $array[2] = 'text';
- switch ($array[2]) {
- // 文本
- case 'text' :
- return $value;
- break;
- // 日期
- case 'date' :
- return !empty($value) ? date($array[3], $value) : null;
- break;
- // 选择框
- case 'selectd' :
- return $array[3][$value] ?? null;
- break;
- // 匿名函数
- case 'function' :
- return isset($array[3]) ? call_user_func($array[3], $row) : null;
- break;
- // 默认
- default :
- break;
- }
- return null;
- }
- /**
- * 解析字段
- *
- * @param $row
- * @param $field
- * @return mixed
- */
- protected static function formattingField($row, $field)
- {
- $newField = explode('.', $field);
- if (count($newField) == 1) {
- return $row[$field];
- }
- foreach ($newField as $item) {
- if (isset($row[$item])) {
- $row = $row[$item];
- } else {
- break;
- }
- }
- return is_array($row) ? false : $row;
- }
- }
|