188 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			188 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | |||
|  | namespace app\service; | |||
|  | 
 | |||
|  | use PhpOffice\PhpSpreadsheet\Shared\Date as EDate; | |||
|  | use PhpOffice\PhpSpreadsheet\Style\Alignment; | |||
|  | use PhpOffice\PhpSpreadsheet\Style\Border; | |||
|  | use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; | |||
|  | use PhpOffice\PhpSpreadsheet\Writer\Xlsx; | |||
|  | use think\file\UploadedFile; | |||
|  | 
 | |||
|  | class File | |||
|  | { | |||
|  |     //上传文件移动到上传文件夹
 | |||
|  |     public static function move(UploadedFile $file) | |||
|  |     { | |||
|  |         $upload_path = 'uploads/' . date('Ymd'); | |||
|  |         $path = app()->getRootPath() . $upload_path; | |||
|  |         $filename = uniqid() . '.' . $file->extension(); | |||
|  |         $upload_filename = '/' . $upload_path . '/' . $filename; | |||
|  |         return [$file->move($path, $filename), $file, $upload_filename]; | |||
|  |     } | |||
|  | 
 | |||
|  |     //导出
 | |||
|  |     static public function export($spreadsheet,$filename) | |||
|  |     { | |||
|  |         $writer = new Xlsx($spreadsheet); | |||
|  |         header("Content-Type: application/force-download"); | |||
|  |         header("Content-Type: application/octet-stream"); | |||
|  |         header("Content-Type: application/download"); | |||
|  |         header('Content-Disposition:inline;filename="'.$filename.'"'); | |||
|  |         header("Content-Transfer-Encoding: binary"); | |||
|  |         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); | |||
|  |         header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | |||
|  |         header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); | |||
|  |         header("Pragma: no-cache"); | |||
|  |         $writer->save('php://output'); | |||
|  |         $spreadsheet->disconnectWorksheets(); | |||
|  |         unset($spreadsheet); | |||
|  |         exit; | |||
|  |     } | |||
|  | 
 | |||
|  |     public static function cancelTimeLimit() | |||
|  |     { | |||
|  |         ini_set('max_execution_time', 0); | |||
|  |         ini_set("memory_limit", -1); | |||
|  |         set_time_limit(0); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 根据header字段获取可配置列的cellId列表 | |||
|  |      * 默认前26列为可配置列A~Z, $headerLength不能超过26 * 27 = 702 | |||
|  |      * | |||
|  |      * @param int $headerLength | |||
|  |      * @return array | |||
|  |      */ | |||
|  |     public static function getCellIds(int $headerLength): array | |||
|  |     { | |||
|  |         $defaultCellIds = range('A', 'Z', 1); | |||
|  |         $cellIds = $defaultCellIds; | |||
|  |         $loop = ceil($headerLength / 26); | |||
|  |         if($loop>1) { | |||
|  |             $maxPrefixIndex = ($loop - 2) >= 25 ? 25 : ($loop - 2); | |||
|  |             for ($prefixIndex = 0; $prefixIndex<= $maxPrefixIndex; $prefixIndex++) { | |||
|  |                 $prefix = $defaultCellIds[$prefixIndex]; | |||
|  |                 $cellIds = array_merge($cellIds, array_map(function ($val) use($prefix) { | |||
|  |                     return $prefix.$val; | |||
|  |                 }, $defaultCellIds)); | |||
|  |             } | |||
|  |         } | |||
|  |         return $cellIds; | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 设置导出表数据 | |||
|  |      * | |||
|  |      * @param Worksheet $sheet 工作表对象 | |||
|  |      * @param array $cellValues 数据信息,二维数组(ps:若字段值需要指定样式以数组格式传递,如[$val, DataType::TYPE_STRING])。第二行开始填充 | |||
|  |      * @param array $header 表头信息, 第一行为表头 | |||
|  |      * @param string $sheetTitle 工作表标题 | |||
|  |      * @param array $cellWidthList 列宽样式,键值对,键名为列序号(从0开始计算) | |||
|  |      * @param array $excelStyle 表数据样式 | |||
|  |      * @param array $defaultList 默认设置样式 | |||
|  |      * @param array $cellWrapList 列换行样式 | |||
|  |      * @return bool | |||
|  |      */ | |||
|  |     public static function setExcelCells(Worksheet $sheet, array $cellValues, array $header, string $sheetTitle = '数据列表', $cellWidthList = [], $excelStyle = [], $defaultList = [], $cellWrapList = []): bool | |||
|  |     { | |||
|  |         $defaultStyle = [ | |||
|  |             'font' => [ | |||
|  |                 'name' => '宋体', | |||
|  |             ], | |||
|  |             'alignment' => [ | |||
|  |                 'horizontal' => Alignment::HORIZONTAL_CENTER,  // 水平居中
 | |||
|  |                 'vertical' => Alignment::VERTICAL_CENTER,  // 垂直居中
 | |||
|  |                 'wrapText' => false, | |||
|  |             ], | |||
|  |             'borders' => [ | |||
|  |                 'allBorders' => [ | |||
|  |                     'borderStyle' => Border::BORDER_THIN, | |||
|  |                     'color' => ['rgb'=>'eeeeee'], | |||
|  |                 ] | |||
|  |             ], | |||
|  |         ]; | |||
|  |         $headerLength = count($header); | |||
|  | 
 | |||
|  |         if($headerLength === 0) return false; | |||
|  |         $cellIds = self::getCellIds($headerLength); | |||
|  |         $lastCellId = $cellIds[$headerLength-1]; | |||
|  |         $contentIndex = 2; | |||
|  |         foreach ($cellValues as $n => $itemCell) { | |||
|  |             foreach ($itemCell as $i => $cellValue) { | |||
|  |                 if(is_array($cellValue)) { | |||
|  |                     $sheet->setCellValueExplicit($cellIds[$i] . $contentIndex, ...$cellValue); | |||
|  |                 } else { | |||
|  |                     $sheet->setCellValue($cellIds[$i] . $contentIndex, $cellValue); | |||
|  |                 } | |||
|  |             } | |||
|  |             $contentIndex++; | |||
|  |         } | |||
|  | 
 | |||
|  |         try { | |||
|  |             $headerStr = 'A1:' . $lastCellId.'1'; | |||
|  |             $bodyStr = 'A2:' . $lastCellId . ($contentIndex - 1); | |||
|  | 
 | |||
|  |             $defaultWidth   = 24; // 默认列宽24个字符
 | |||
|  |             $fontSize       = 12; // 默认字体大小为12号
 | |||
|  |             if(!empty($defaultList)) { | |||
|  |                 if(isset($defaultList['cell_width']) && is_numeric($defaultList['cell_width']) && $defaultList['cell_width'] > 0) { | |||
|  |                     $defaultWidth = $defaultList['cell_width']; | |||
|  |                 } | |||
|  |                 if(isset($defaultList['font_size']) && is_numeric($defaultList['font_size']) && $defaultList['font_size'] > 0) { | |||
|  |                     $fontSize = $defaultList['font_size']; | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  | 
 | |||
|  |             $sheet->setTitle(empty($sheetTitle) ? '数据列表': $sheetTitle); | |||
|  |             $sheet->getDefaultColumnDimension()->setAutoSize($fontSize); | |||
|  |             $sheet->getStyle($headerStr)->getFont()->setBold(false)->setSize($fontSize+2); | |||
|  |             $sheet->getDefaultColumnDimension()->setWidth($defaultWidth); | |||
|  |             $sheet->fromArray($header, null, 'A1'); | |||
|  |             $sheet->getStyle($headerStr)->applyFromArray($defaultStyle); | |||
|  |             $sheet->getStyle($bodyStr)->applyFromArray(empty($excelStyle) ? $defaultStyle : $excelStyle); | |||
|  | 
 | |||
|  |             // 自定义列宽
 | |||
|  |             if(!empty($cellWidthList)) { | |||
|  |                 foreach ($cellWidthList as $cellId => $widthVal) { | |||
|  |                     if(isset($cellIds[$cellId]) && is_numeric($widthVal) && $widthVal > 0) { | |||
|  |                         $sheet->getColumnDimension($cellIds[$cellId])->setWidth($widthVal); | |||
|  |                     } | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             //自定义列是否换行
 | |||
|  |             if(!empty($cellWrapList)) { | |||
|  |                 foreach ($cellWrapList as $cellId => $boolVal) { | |||
|  |                     if(isset($cellIds[$cellId])) { | |||
|  |                         $wrap = $boolVal ? true : false; | |||
|  |                         $sheet->getStyle($cellIds[$cellId])->getAlignment()->setWrapText($wrap); | |||
|  |                     } | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             return true; | |||
|  |         } catch (\Exception $e) { | |||
|  |             return false; | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     // excel导入时间转换
 | |||
|  |     public static function getExcelTime($timeStr, $format = 'Y-m-d') | |||
|  |     { | |||
|  |         $timezone = ini_get('date.timezone'); | |||
|  |         $timeStr = trim($timeStr); | |||
|  |         if (!empty($timeStr)) { | |||
|  |             if (is_numeric($timeStr)) { | |||
|  |                 $toTimestamp = EDate::excelToTimestamp($timeStr, $timezone); | |||
|  |                 $timeStr = date($format, $toTimestamp); | |||
|  |             } else { | |||
|  |                 $toTimestamp = strtotime($timeStr); | |||
|  |                 $timeStr = ($toTimestamp === false) ? '' : date($format, $toTimestamp); | |||
|  |             } | |||
|  |         } else { | |||
|  |             $timeStr = ''; | |||
|  |         } | |||
|  |         return $timeStr; | |||
|  |     } | |||
|  | } |