| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- <?php
- namespace App\Exports;
- use Maatwebsite\Excel\Concerns\WithEvents;
- use Maatwebsite\Excel\Concerns\WithTitle;
- use Maatwebsite\Excel\Events\AfterSheet;
- use PhpOffice\PhpSpreadsheet\Style\Alignment;
- use PhpOffice\PhpSpreadsheet\Style\Border;
- use PhpOffice\PhpSpreadsheet\Style\Borders;
- use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
- class ManMonthlyWorkHourSheetExport implements WithEvents, WithTitle
- {
- protected $monthName;
- protected $data;
- protected $daysInMonth;
- public function __construct(string $monthName, array $data, int $daysInMonth)
- {
- $this->monthName = $monthName;
- $this->data = $data;
- $this->daysInMonth = $daysInMonth;
- }
- public function title(): string
- {
- return $this->monthName;
- }
- public function registerEvents(): array
- {
- return [
- AfterSheet::class => function (AfterSheet $event) {
- $sheet = $event->sheet->getDelegate();
- // 计算最大列(项目B + 姓名C + 天数)
- $totalColNum = 2 + $this->daysInMonth;
- $highestColumn = Coordinate::stringFromColumnIndex($totalColNum);
- // --- 1. 第一行:主标题 ---
- $sheet->mergeCells("A1:{$highestColumn}1");
- $sheet->setCellValue('A1', "{$this->monthName}研发人员工时统计表");
- $sheet->getStyle('A1')->getFont()->setSize(14);
- $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
- // --- 2. 第二行:单位行 ---
- $sheet->mergeCells("A2:{$highestColumn}2");
- $sheet->setCellValue('A2', "单位:");
- $sheet->getStyle('A2')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
- // --- 3. 第三行表头设置 ---
- // (1) A3: 项目名称 (独立单元格)
- $sheet->setCellValue('A3', "项目名称");
- $sheet->getColumnDimension('A')->setWidth(14);
- // (2) B3: 人员名称/日期 (斜线分割单元格)
- $sheet->setCellValue('B3', " 日期 \n人员名称");
- $sheet->getStyle('B3')->getAlignment()->setWrapText(true);
- $sheet->getStyle('B3')->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
- $sheet->getStyle('B3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
- $sheet->getColumnDimension('B')->setWidth(16);
- // 绘制 B3 斜线
- $sheet->getStyle('B3')->getBorders()->applyFromArray([
- 'diagonal' => [
- 'borderStyle' => Border::BORDER_THIN,
- 'color' => ['rgb' => '000000'],
- ],
- ]);
- $sheet->getStyle('B3')->getBorders()->setDiagonalDirection(Borders::DIAGONAL_DOWN);
- // (3) C3 往后: 动态日期 (1, 2, 3...)
- for ($day = 1; $day <= $this->daysInMonth; $day++) {
- $colLetter = Coordinate::stringFromColumnIndex($day + 2); // 从 C 列开始
- $sheet->setCellValue($colLetter . '3', $day);
- $sheet->getColumnDimension($colLetter)->setWidth(8);
- }
- // 设置第三行行高
- $sheet->getRowDimension(3)->setRowHeight(50);
- // --- 4. 写入数据行 (从第4行开始) ---
- $dataStartRow = 4;
- if (!empty($this->data)) {
- foreach ($this->data as $rowIndex => $row) {
- $currentRow = $dataStartRow + $rowIndex;
- foreach ($row as $colIndex => $cellValue) {
- $colLetter = Coordinate::stringFromColumnIndex($colIndex + 1);
- $sheet->setCellValue($colLetter . $currentRow, $cellValue);
- }
- }
- }
- // --- 5. 全局样式微调 ---
- $highestRow = $sheet->getHighestRow();
- // 1. 设置工时数据区域的格式为数字,并保留两位小数
- $dataRange = "C4:{$highestColumn}{$highestRow}";
- $sheet->getStyle($dataRange)->getNumberFormat()->setFormatCode('#,##0.00');
- // 或者用 NumberFormat::FORMAT_NUMBER_00
- // 所有单元格垂直居中
- $sheet->getStyle("A1:{$highestColumn}{$highestRow}")->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
- // 表头及日期数据水平居中 (排除 A3 和 B3)
- $sheet->getStyle("A3:{$highestColumn}{$highestRow}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
- $sheet->getStyle('B3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); // 斜线格保持左对齐
- // 添加表格边框 (从 A3 开始)
- $sheet->getStyle("A3:{$highestColumn}{$highestRow}")->applyFromArray([
- 'borders' => [
- 'allBorders' => [
- 'borderStyle' => Border::BORDER_THIN,
- ],
- ],
- ]);
- },
- ];
- }
- }
|