201 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			201 lines
		
	
	
		
			7.5 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 Excel
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    // 导出excel默认样式
							 | 
						|||
| 
								 | 
							
								    public static array $excelStyle = [
							 | 
						|||
| 
								 | 
							
								        'font'      => [
							 | 
						|||
| 
								 | 
							
								            'name' => '宋体',
							 | 
						|||
| 
								 | 
							
								        ],
							 | 
						|||
| 
								 | 
							
								        'alignment' => [
							 | 
						|||
| 
								 | 
							
								            'horizontal' => Alignment::HORIZONTAL_CENTER,  // 水平居中
							 | 
						|||
| 
								 | 
							
								            'vertical'   => Alignment::VERTICAL_CENTER,  // 垂直居中
							 | 
						|||
| 
								 | 
							
								            'wrapText'   => true,
							 | 
						|||
| 
								 | 
							
								        ],
							 | 
						|||
| 
								 | 
							
								        'borders'   => [
							 | 
						|||
| 
								 | 
							
								            'allBorders' => [
							 | 
						|||
| 
								 | 
							
								                'borderStyle' => Border::BORDER_THIN,
							 | 
						|||
| 
								 | 
							
								                'color'       => ['rgb' => 'eeeeee'],
							 | 
						|||
| 
								 | 
							
								            ]
							 | 
						|||
| 
								 | 
							
								        ],
							 | 
						|||
| 
								 | 
							
								    ];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static array $defaultSetting = [
							 | 
						|||
| 
								 | 
							
								        'cell_width'    => 30, // 默认列宽
							 | 
						|||
| 
								 | 
							
								        'font_size'     => 12, // 默认excel内容字体大小
							 | 
						|||
| 
								 | 
							
								    ];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    //导出
							 | 
						|||
| 
								 | 
							
								    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;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |