$path['dirname']]); $excel->openFile($path['basename']) ->openSheet(); $title = $excel->nextRow(); $type = array_pad([], count($title), \Vtiful\Kernel\Excel::TYPE_STRING); foreach($format as $k => $v) { $type[array_search($v, $title)] = \Vtiful\Kernel\Excel::TYPE_TIMESTAMP; } $contents = $excel->setType($type) ->getSheetData(); $contents = array_merge([0 => $title], $contents); $highestRow = count($contents); foreach ($contents as $i => $row) { $key = $i + 1; foreach($format as $k => $v) { $index = array_search($v, $title); if($row[$index] && is_int($row[$index])) $row[$index] = date('Y-m-d H:i:s', $row[$index]); } $data = [ 'line' => $key, 'contents' => $row ]; $data['post'] = $post; $data['highestRow'] = $highestRow; if ($output) { $this->_output("第{$key}行,{$data['contents'][0]}处理中..."); } list($rs, $msg, $level) = call_user_func_array($callback, array_values($data)); if ($rs == false) { //if ($output) { // $this->_output("第{$key}行,{$data['contents'][0]}处理失败:{$msg}。", 'error'); //} //显示上一行报错信息 if($output == 'lastrow' && $msg){ $line_key = $i; $this->_output("第{$line_key}行失败:{$msg}。", 'error'); }elseif($output){ //默认显示报错的下一行 $this->_output("第{$key}行,{$data['contents'][0]}处理失败:{$msg}。", 'error'); } return [false, $msg]; } if ($output || $msg) { //显示上一行报错信息 if($output == 'lastrow' && $msg){ if($highestRow == $key){ $line_key = $key; }else{ $line_key = $i; } $this->_output("第{$line_key}行,{$msg};", 'error'); }else{ $this->_output("第{$key}行,{$data['contents'][0]}".$msg??'处理完成', $level??'notice'); } } } return [true, '成功']; } catch (\Exception $e) { $msg = $e->getMessage(); $this->_output($msg); return [false, $msg]; } } /** * 导出Excel文件,支持单工作表和多工作表 * * @param string $filename 文件名 * @param array $data 数据,支持两种格式: * 1. 单工作表:[0 => [标题行], 1 => [数据行1], ...] * 2. 多工作表:[['sheet_name' => '工作表名', 'data' => [数据]], ...] * @return void * @author **/ public function export($filename, $data) { try { $config = [ 'path' => kernel::single('ome_func')->getTmpDir() // xlsx文件保存路径 ]; $excel = new \Vtiful\Kernel\Excel($config); $fileTmpName = time().uniqid().rand(10,99).'.xlsx'; // 检查是否为多工作表格式 $isMultiSheet = false; if (!empty($data) && is_array($data)) { $firstItem = reset($data); if (is_array($firstItem) && isset($firstItem['sheet_name']) && isset($firstItem['data'])) { $isMultiSheet = true; } } if ($isMultiSheet) { // 多工作表模式 $firstSheet = true; foreach ($data as $sheetInfo) { $sheetName = $sheetInfo['sheet_name']; $sheetData = $sheetInfo['data']; if ($firstSheet) { // 创建第一个工作表 $filePath = $excel->fileName($fileTmpName, $sheetName); if ($sheetData) { $filePath = $filePath->data($sheetData); } $firstSheet = false; } else { // 添加其他工作表 $filePath = $filePath->addSheet($sheetName); if ($sheetData) { $filePath = $filePath->data($sheetData); } } } } else { // 单工作表模式(保持向后兼容) $filePath = $excel->fileName($fileTmpName, 'sheet1'); if ($data) { $filePath = $filePath->data($data); } } $filePath = $filePath->output(); header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); header('Content-Disposition: attachment;filename="' . $filename); header('Content-Transfer-Encoding: binary'); header('Cache-Control: must-revalidate'); header('Cache-Control: max-age=0'); header('Pragma: public'); header('Content-Length: ' . filesize($filePath)); $savePath = 'php://output'; if (copy($filePath, $savePath) === false) { // Throw exception } // Delete temporary file @unlink($filePath); } catch (Exception $e) { } } public function save($filename, $data) { try { $config = [ 'path' => kernel::single('ome_func')->getTmpDir() // xlsx文件保存路径 ]; $excel = new \Vtiful\Kernel\Excel($config); $fileTmpName = time().uniqid().rand(10,99).'.xlsx'; // fileName 会自动创建一个工作表,你可以自定义该工作表名称,工作表名称为可选参数 $filePath = $excel->fileName($fileTmpName, 'sheet1'); if($data) { $filePath = $filePath->data($data); } $filePath = $filePath->output(); if (copy($filePath, $filename) === false) { // Throw exception } // Delete temporary file @unlink($filePath); } catch (Exception $e) { } } public function _output($msg, $level='notice') { $msg = addslashes($msg); echo sprintf("", $msg); if ($level != 'notice') { echo << var c = parent.$('iMsg').clone().setStyle('color','#8a1f11') c.inject('iMsg','after') JS; } flush(); ob_flush(); } }