data = $data; $this->month = $month; $this->year = $year; $this->workingDays = $workingDays; $this->daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year); } public function array(): array { // Lấy headers $headers = $this->headings(); // Lấy dữ liệu người dùng $userRows = []; foreach ($this->data as $user) { // Kiểm tra permission staff if (!isset($user['user']['permission']) || $user['user']['permission'] !== 'staff') { continue; } $row = [ $user['user']['name'] ?? 'Unknown', 0, // Total days $this->workingDays, // Off days (initialize with working days) ]; $totalDays = 0; // Add data for each day in month for ($day = 1; $day <= $this->daysInMonth; $day++) { $dayData = ''; if (isset($user['history'])) { foreach ($user['history'] as $history) { if ($history['day'] === $day) { $total = $history['total'] ?? 0; if ($total >= 7 * 3600) { $dayData = '1'; $totalDays += 1; } else if ($total >= 3.5 * 3600) { $dayData = '0.5'; $totalDays += 0.5; } break; } } } $row[] = $dayData; } // Update total and off days $row[1] = $totalDays; $row[2] = $this->workingDays - $totalDays; // Add Notes column with formatted content $notes = []; if (isset($user['history'])) { foreach ($user['history'] as $history) { if (!empty($history['notes'])) { $dayNotes = []; foreach ($history['notes'] as $note) { $dayNotes[] = "- {$note['reasonName']} ({$note['timeTypeName']}): {$note['note']}"; } if (!empty($dayNotes)) { $notes[] = "Day {$history['day']}:\n" . implode("\n", $dayNotes); } } } } $row[] = !empty($notes) ? implode("\n\n", $notes) : ''; $userRows[] = $row; } return array_merge($headers, $userRows); } public function headings(): array { $firstRow = ['Day', '', '']; // Second row: Day of week $secondRow = ['', '', '']; $date = Carbon::create($this->year, $this->month, 1); for ($day = 1; $day <= $this->daysInMonth; $day++) { $firstRow[] = $day; $secondRow[] = $date->format('D'); $date->addDay(); } // Add Notes column $firstRow[] = 'Notes'; $secondRow[] = ''; return [$firstRow, $secondRow]; } public function styles(Worksheet $sheet) { $lastColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4); // Title and working days $sheet->mergeCells("A1:{$lastColumn}1"); $sheet->setCellValue('A1', "DANH SÁCH CHẤM CÔNG THÁNG {$this->month} NĂM {$this->year}"); $sheet->mergeCells("A2:{$lastColumn}2"); $sheet->setCellValue('A2', "Số ngày làm việc: {$this->workingDays}"); // Merge cells for "Day" title and set value $sheet->mergeCells("A3:C3"); $sheet->setCellValue('A3', 'Day'); // Set values for A4, B4, C4 $sheet->setCellValue('A4', 'User'); $sheet->setCellValue('B4', 'Total'); $sheet->setCellValue('C4', 'Off'); // Calculate last row (2 title rows + 2 header rows + data rows) $lastRow = count($this->data) + 4; // Styling $sheet->getStyle("A1:{$lastColumn}1")->getFont()->setBold(true)->setSize(14); $sheet->getStyle("A2:{$lastColumn}2")->getFont()->setBold(true); $sheet->getStyle("A3:{$lastColumn}4")->getFont()->setBold(true); // Border style $borderStyle = [ 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, ], ], ]; // Apply borders to the data area $sheet->getStyle("A1:{$lastColumn}{$lastRow}")->applyFromArray($borderStyle); // Center align all cells except Notes column $sheet->getStyle("A1:{$lastColumn}{$lastRow}") ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER) ->setVertical(Alignment::VERTICAL_CENTER); // Left align Notes column $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4); $sheet->getStyle("{$noteColumn}5:{$noteColumn}{$lastRow}") ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_LEFT); // Set column widths $sheet->getColumnDimension('A')->setWidth(30); $sheet->getColumnDimension('B')->setWidth(10); $sheet->getColumnDimension('C')->setWidth(10); for ($i = 4; $i <= $this->daysInMonth + 3; $i++) { $sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i))->setWidth(5); } // Set width for Note column $sheet->getColumnDimension($noteColumn)->setWidth(40); return []; } }