data = $data; $this->year = Carbon::now()->year; } public function headings(): array { $months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; return array_merge( ['No.', 'User'], $months, ['Total', 'Off', 'Remaining', 'Notes'] ); } public function array(): array { $headers = $this->headings(); // Lấy tiêu đề $rows = []; $stt = 0; foreach ($this->data as $index => $user) { $totalDayOff = 0; $totalDayLeave = $user['leaveDay']['ld_day_total'] + $user['leaveDay']['ld_date_additional']; // Tính tổng ngày nghỉ theo tháng $monthlyLeaves = array_fill(1, 12, 0); foreach ($user['monthlyLeaveDays'] as $leaveDay) { $monthlyLeaves[$leaveDay['month']] += $leaveDay['leave_days']; $totalDayOff += $leaveDay['leave_days']; } // Tạo dòng dữ liệu $row = [ $stt + 1, $user['user']['name'] ]; // Thêm dữ liệu các tháng for ($month = 1; $month <= 12; $month++) { $row[] = $monthlyLeaves[$month] ?: ''; } // Thêm tổng số ngày $row[] = $totalDayLeave; $row[] = $totalDayOff; $row[] = $totalDayLeave - $totalDayOff; $row[] = $user['leaveDay']['ld_note'] ?? ''; $rows[] = $row; $stt++; } return array_merge([$headers], $rows); // Thêm tiêu đề vào đầu mảng } public function registerEvents(): array { return [ AfterSheet::class => function(AfterSheet $event) { $sheet = $event->sheet->getDelegate(); $lastRow = count($this->data) + 2; $noteColumn = 'R'; // Cột Notes // Xử lý đặc biệt cho cột Notes $sheet->getStyle("{$noteColumn}3:{$noteColumn}{$lastRow}") ->getAlignment() ->setWrapText(true) ->setVertical(Alignment::VERTICAL_TOP) ->setHorizontal(Alignment::HORIZONTAL_LEFT); // Tắt auto-size cho cột Notes và set độ rộng cố định $sheet->getColumnDimension($noteColumn) ->setAutoSize(false) ->setWidth(60); // Tự động điều chỉnh chiều cao cho từng dòng có nội dung for ($row = 3; $row <= $lastRow; $row++) { $cellValue = $sheet->getCell($noteColumn . $row)->getValue(); if (!empty($cellValue)) { // Tính toán chiều cao dựa trên nội dung $sheet->getRowDimension($row)->setRowHeight(-1); // Tính toán lại chiều cao dựa trên số dòng trong nội dung $lineCount = substr_count($cellValue, "\n") + 1; $minHeight = max(30, $lineCount * 15); // 15 pixels cho mỗi dòng // Lấy chiều cao hiện tại sau khi auto-size $currentHeight = $sheet->getRowDimension($row)->getRowHeight(); // Nếu chiều cao tự động nhỏ hơn chiều cao tối thiểu, sử dụng chiều cao tối thiểu if ($currentHeight < $minHeight) { $sheet->getRowDimension($row)->setRowHeight($minHeight); } } else { $sheet->getRowDimension($row)->setRowHeight(30); } } // Refresh các tính toán của Excel $sheet->calculateColumnWidths(); }, ]; } public function styles(Worksheet $sheet) { $lastRow = count($this->data) + 2; $lastColumn = 'R'; // Thêm và style title $sheet->mergeCells("A1:{$lastColumn}1"); $sheet->setCellValue('A1', "DANH SÁCH NGÀY NGHỈ NĂM {$this->year}"); $sheet->getStyle("A1:{$lastColumn}1")->applyFromArray([ 'font' => [ 'bold' => true, 'size' => 14 ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER ] ]); // Style cho header (dời xuống row 2) $sheet->getStyle("A2:{$lastColumn}2")->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER ] ]); // Style cho toàn bộ bảng (bắt đầu từ row 1) $sheet->getStyle("A1:{$lastColumn}{$lastRow}")->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN ] ], 'alignment' => [ 'vertical' => Alignment::VERTICAL_CENTER ] ]); // Căn giữa cho các cột số liệu (điều chỉnh range bắt đầu từ row 3) for ($col = 'C'; $col <= 'P'; $col++) { $sheet->getStyle("{$col}3:{$col}{$lastRow}") ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER); } // Set độ rộng cột $sheet->getColumnDimension('A')->setWidth(5); // No. $sheet->getColumnDimension('B')->setWidth(30); // User // Các tháng for ($i = 'C'; $i <= 'N'; $i++) { $sheet->getColumnDimension($i)->setWidth(8); } $sheet->getColumnDimension('O')->setWidth(8); // Total $sheet->getColumnDimension('P')->setWidth(8); // Off $sheet->getColumnDimension('Q')->setWidth(12); // Remaining $sheet->getColumnDimension('R')->setWidth(30); // Notes // Điều chỉnh style cho cột Notes $sheet->getStyle("R3:R{$lastRow}") ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_LEFT) ->setVertical(Alignment::VERTICAL_TOP) ->setWrapText(true); return $sheet; } }