Bổ sung nút report excel trang timekeeping , leave management
This commit is contained in:
		
							parent
							
								
									93030b73c7
								
							
						
					
					
						commit
						7fdf6f3e25
					
				| 
						 | 
					@ -151,9 +151,14 @@ class LeaveManagementController extends Controller
 | 
				
			||||||
            return response()->json(['status' => false, 'message' => 'No data found']);
 | 
					            return response()->json(['status' => false, 'message' => 'No data found']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Lọc chỉ lấy user có permission bao gồm staff
 | 
				
			||||||
 | 
					        $staffData = $leaveDays->filter(function($user) {
 | 
				
			||||||
 | 
					            return isset($user['user']['permission']) && strpos($user['user']['permission'], 'staff') !== false;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentDate = date('d_His');
 | 
					        $currentDate = date('d_His');
 | 
				
			||||||
        return Excel::download(
 | 
					        return Excel::download(
 | 
				
			||||||
            new LeaveManagementExport($leaveDays),
 | 
					            new LeaveManagementExport($staffData),
 | 
				
			||||||
            "LeaveManagement_{$year}_{$currentDate}.xlsx"
 | 
					            "LeaveManagement_{$year}_{$currentDate}.xlsx"
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,9 +205,9 @@ class TimekeepingController extends Controller
 | 
				
			||||||
            return response()->json(['status' => false, 'message' => 'No data found']);
 | 
					            return response()->json(['status' => false, 'message' => 'No data found']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Lọc chỉ lấy user có permission staff
 | 
					        // Lọc chỉ lấy user có permission bao gồm staff
 | 
				
			||||||
        $staffData = array_filter($responseData['data'], function($user) {
 | 
					        $staffData = array_filter($responseData['data'], function($user) {
 | 
				
			||||||
            return isset($user['user']['permission']) && $user['user']['permission'] === 'staff';
 | 
					            return isset($user['user']['permission']) && strpos($user['user']['permission'], 'staff') !== false;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $currentDate = date('d_His');
 | 
					        $currentDate = date('d_His');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,13 +4,15 @@ namespace App\Exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\FromArray;
 | 
					use Maatwebsite\Excel\Concerns\FromArray;
 | 
				
			||||||
 | 
					use Maatwebsite\Excel\Concerns\WithEvents;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
 | 
					use Maatwebsite\Excel\Concerns\WithHeadings;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\WithStyles;
 | 
					use Maatwebsite\Excel\Concerns\WithStyles;
 | 
				
			||||||
 | 
					use Maatwebsite\Excel\Events\AfterSheet;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 | 
					use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Style\Border;
 | 
					use PhpOffice\PhpSpreadsheet\Style\Border;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
 | 
					use PhpOffice\PhpSpreadsheet\Style\Alignment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LeaveManagementExport implements FromArray, WithHeadings, WithStyles
 | 
					class LeaveManagementExport implements FromArray, WithHeadings, WithStyles, WithEvents
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $data;
 | 
					    protected $data;
 | 
				
			||||||
    protected $year;
 | 
					    protected $year;
 | 
				
			||||||
| 
						 | 
					@ -36,6 +38,7 @@ class LeaveManagementExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
        $headers = $this->headings(); // Lấy tiêu đề
 | 
					        $headers = $this->headings(); // Lấy tiêu đề
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rows = [];
 | 
					        $rows = [];
 | 
				
			||||||
 | 
					        $stt = 0;
 | 
				
			||||||
        foreach ($this->data as $index => $user) {
 | 
					        foreach ($this->data as $index => $user) {
 | 
				
			||||||
            $totalDayOff = 0;
 | 
					            $totalDayOff = 0;
 | 
				
			||||||
            $totalDayLeave = $user['leaveDay']['ld_day'] + $user['leaveDay']['ld_date_additional'];
 | 
					            $totalDayLeave = $user['leaveDay']['ld_day'] + $user['leaveDay']['ld_date_additional'];
 | 
				
			||||||
| 
						 | 
					@ -49,7 +52,7 @@ class LeaveManagementExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Tạo dòng dữ liệu
 | 
					            // Tạo dòng dữ liệu
 | 
				
			||||||
            $row = [
 | 
					            $row = [
 | 
				
			||||||
                $index + 1,
 | 
					                $stt + 1,
 | 
				
			||||||
                $user['user']['name']
 | 
					                $user['user']['name']
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,11 +68,61 @@ class LeaveManagementExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
            $row[] = $user['leaveDay']['ld_note'] ?? '';
 | 
					            $row[] = $user['leaveDay']['ld_note'] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $rows[] = $row;
 | 
					            $rows[] = $row;
 | 
				
			||||||
 | 
					            $stt++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return array_merge([$headers], $rows); // Thêm tiêu đề vào đầu mảng
 | 
					        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)
 | 
					    public function styles(Worksheet $sheet)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $lastRow = count($this->data) + 2;
 | 
					        $lastRow = count($this->data) + 2;
 | 
				
			||||||
| 
						 | 
					@ -129,6 +182,13 @@ class LeaveManagementExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
        $sheet->getColumnDimension('Q')->setWidth(12); // Remaining
 | 
					        $sheet->getColumnDimension('Q')->setWidth(12); // Remaining
 | 
				
			||||||
        $sheet->getColumnDimension('R')->setWidth(30); // Notes
 | 
					        $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;
 | 
					        return $sheet;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
| 
						 | 
					@ -4,13 +4,15 @@ namespace App\Exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\FromArray;
 | 
					use Maatwebsite\Excel\Concerns\FromArray;
 | 
				
			||||||
 | 
					use Maatwebsite\Excel\Concerns\WithEvents;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
 | 
					use Maatwebsite\Excel\Concerns\WithHeadings;
 | 
				
			||||||
use Maatwebsite\Excel\Concerns\WithStyles;
 | 
					use Maatwebsite\Excel\Concerns\WithStyles;
 | 
				
			||||||
 | 
					use Maatwebsite\Excel\Events\AfterSheet;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 | 
					use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Style\Border;
 | 
					use PhpOffice\PhpSpreadsheet\Style\Border;
 | 
				
			||||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
 | 
					use PhpOffice\PhpSpreadsheet\Style\Alignment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
					class TimekeepingExport implements FromArray, WithHeadings, WithStyles, WithEvents
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $data;
 | 
					    protected $data;
 | 
				
			||||||
    protected $month;
 | 
					    protected $month;
 | 
				
			||||||
| 
						 | 
					@ -27,6 +29,55 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
        $this->daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
 | 
					        $this->daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function registerEvents(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            AfterSheet::class => function(AfterSheet $event) {
 | 
				
			||||||
 | 
					                $sheet = $event->sheet->getDelegate();
 | 
				
			||||||
 | 
					                $lastRow = count($this->data) + 4;
 | 
				
			||||||
 | 
					                $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Xử lý đặc biệt cho cột Notes
 | 
				
			||||||
 | 
					                $sheet->getStyle("{$noteColumn}5:{$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 = 5; $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 array(): array
 | 
					    public function array(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Lấy headers
 | 
					        // Lấy headers
 | 
				
			||||||
| 
						 | 
					@ -35,11 +86,6 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
        // Lấy dữ liệu người dùng
 | 
					        // Lấy dữ liệu người dùng
 | 
				
			||||||
        $userRows = [];
 | 
					        $userRows = [];
 | 
				
			||||||
        foreach ($this->data as $user) {
 | 
					        foreach ($this->data as $user) {
 | 
				
			||||||
            // Kiểm tra permission staff
 | 
					 | 
				
			||||||
            if (!isset($user['user']['permission']) || $user['user']['permission'] !== 'staff') {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $row = [
 | 
					            $row = [
 | 
				
			||||||
                $user['user']['name'] ?? 'Unknown',
 | 
					                $user['user']['name'] ?? 'Unknown',
 | 
				
			||||||
                0, // Total days
 | 
					                0, // Total days
 | 
				
			||||||
| 
						 | 
					@ -120,6 +166,8 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
    public function styles(Worksheet $sheet)
 | 
					    public function styles(Worksheet $sheet)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $lastColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
 | 
					        $lastColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
 | 
				
			||||||
 | 
					        $lastRow = count($this->data) + 4;
 | 
				
			||||||
 | 
					        $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Title and working days
 | 
					        // Title and working days
 | 
				
			||||||
        $sheet->mergeCells("A1:{$lastColumn}1");
 | 
					        $sheet->mergeCells("A1:{$lastColumn}1");
 | 
				
			||||||
| 
						 | 
					@ -136,9 +184,6 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
        $sheet->setCellValue('B4', 'Total');
 | 
					        $sheet->setCellValue('B4', 'Total');
 | 
				
			||||||
        $sheet->setCellValue('C4', 'Off');
 | 
					        $sheet->setCellValue('C4', 'Off');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Calculate last row (2 title rows + 2 header rows + data rows)
 | 
					 | 
				
			||||||
        $lastRow = count($this->data) + 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Styling
 | 
					        // Styling
 | 
				
			||||||
        $sheet->getStyle("A1:{$lastColumn}1")->getFont()->setBold(true)->setSize(14);
 | 
					        $sheet->getStyle("A1:{$lastColumn}1")->getFont()->setBold(true)->setSize(14);
 | 
				
			||||||
        $sheet->getStyle("A2:{$lastColumn}2")->getFont()->setBold(true);
 | 
					        $sheet->getStyle("A2:{$lastColumn}2")->getFont()->setBold(true);
 | 
				
			||||||
| 
						 | 
					@ -162,11 +207,33 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
            ->setHorizontal(Alignment::HORIZONTAL_CENTER)
 | 
					            ->setHorizontal(Alignment::HORIZONTAL_CENTER)
 | 
				
			||||||
            ->setVertical(Alignment::VERTICAL_CENTER);
 | 
					            ->setVertical(Alignment::VERTICAL_CENTER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Left align Notes column
 | 
					        // Left align Notes column và bật wrap text
 | 
				
			||||||
        $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
 | 
					 | 
				
			||||||
        $sheet->getStyle("{$noteColumn}5:{$noteColumn}{$lastRow}")
 | 
					        $sheet->getStyle("{$noteColumn}5:{$noteColumn}{$lastRow}")
 | 
				
			||||||
            ->getAlignment()
 | 
					            ->getAlignment()
 | 
				
			||||||
            ->setHorizontal(Alignment::HORIZONTAL_LEFT);
 | 
					            ->setHorizontal(Alignment::HORIZONTAL_LEFT)
 | 
				
			||||||
 | 
					            ->setVertical(Alignment::VERTICAL_TOP)
 | 
				
			||||||
 | 
					            ->setWrapText(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set width for Note column - tăng độ rộng để hiển thị tốt hơn
 | 
				
			||||||
 | 
					        $sheet->getColumnDimension($noteColumn)->setWidth(60);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Tự động điều chỉnh chiều cao cho các dòng có nội dung Notes
 | 
				
			||||||
 | 
					        for ($row = 5; $row <= $lastRow; $row++) {
 | 
				
			||||||
 | 
					            $cellValue = $sheet->getCell($noteColumn . $row)->getValue();
 | 
				
			||||||
 | 
					            if (!empty($cellValue)) {
 | 
				
			||||||
 | 
					                // Đết chiều cao tự động
 | 
				
			||||||
 | 
					                $sheet->getRowDimension($row)->setRowHeight(-1);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // Đảm bảo chiều cao tối thiểu
 | 
				
			||||||
 | 
					                $currentHeight = $sheet->getRowDimension($row)->getRowHeight();
 | 
				
			||||||
 | 
					                if ($currentHeight < 30) {
 | 
				
			||||||
 | 
					                    $sheet->getRowDimension($row)->setRowHeight(30);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // Chiều cao mặc định cho các dòng không có note
 | 
				
			||||||
 | 
					                $sheet->getRowDimension($row)->setRowHeight(30);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set column widths
 | 
					        // Set column widths
 | 
				
			||||||
        $sheet->getColumnDimension('A')->setWidth(30);
 | 
					        $sheet->getColumnDimension('A')->setWidth(30);
 | 
				
			||||||
| 
						 | 
					@ -176,9 +243,6 @@ class TimekeepingExport implements FromArray, WithHeadings, WithStyles
 | 
				
			||||||
            $sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i))->setWidth(5);
 | 
					            $sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i))->setWidth(5);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set width for Note column
 | 
					 | 
				
			||||||
        $sheet->getColumnDimension($noteColumn)->setWidth(40);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [];
 | 
					        return [];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ import {
 | 
				
			||||||
  Textarea,
 | 
					  Textarea,
 | 
				
			||||||
  TextInput,
 | 
					  TextInput,
 | 
				
			||||||
  Tooltip,
 | 
					  Tooltip,
 | 
				
			||||||
 | 
					  Modal,
 | 
				
			||||||
} from '@mantine/core'
 | 
					} from '@mantine/core'
 | 
				
			||||||
import { useDisclosure } from '@mantine/hooks'
 | 
					import { useDisclosure } from '@mantine/hooks'
 | 
				
			||||||
import { notifications } from '@mantine/notifications'
 | 
					import { notifications } from '@mantine/notifications'
 | 
				
			||||||
| 
						 | 
					@ -143,6 +144,9 @@ const Timekeeping = () => {
 | 
				
			||||||
  const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
 | 
					  const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
 | 
				
			||||||
  const [dataReason, setDataReason] = useState<DataReason[]>([])
 | 
					  const [dataReason, setDataReason] = useState<DataReason[]>([])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [exportModalOpened, setExportModalOpened] = useState(false)
 | 
				
			||||||
 | 
					  const [exportOption, setExportOption] = useState('default')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const getListMasterByType = async (type: string) => {
 | 
					  const getListMasterByType = async (type: string) => {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const params = {
 | 
					      const params = {
 | 
				
			||||||
| 
						 | 
					@ -437,7 +441,7 @@ const Timekeeping = () => {
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleExport = async () => {
 | 
					  const handleExport = async (option: string) => {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const timestamp = moment().format('DDMMYYYY_HHmmss')
 | 
					      const timestamp = moment().format('DDMMYYYY_HHmmss')
 | 
				
			||||||
      const fileName = `Timekeeping_${date.month}_${date.year}_${timestamp}.xlsx`
 | 
					      const fileName = `Timekeeping_${date.month}_${date.year}_${timestamp}.xlsx`
 | 
				
			||||||
| 
						 | 
					@ -447,10 +451,12 @@ const Timekeeping = () => {
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          month: date.month,
 | 
					          month: date.month,
 | 
				
			||||||
          year: date.year,
 | 
					          year: date.year,
 | 
				
			||||||
          working_days: workingDays
 | 
					          working_days: workingDays,
 | 
				
			||||||
 | 
					          option: option
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        fileName
 | 
					        fileName
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 | 
					      setExportModalOpened(false)
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      console.error('Export error:', error)
 | 
					      console.error('Export error:', error)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -707,7 +713,7 @@ const Timekeeping = () => {
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </Tooltip>
 | 
					            </Tooltip>
 | 
				
			||||||
            <Button 
 | 
					            <Button 
 | 
				
			||||||
              onClick={handleExport} 
 | 
					              onClick={() => setExportModalOpened(true)} 
 | 
				
			||||||
              size="xs" 
 | 
					              size="xs" 
 | 
				
			||||||
              ml="xl"
 | 
					              ml="xl"
 | 
				
			||||||
              leftSection={<IconFileExcel size={16} />}
 | 
					              leftSection={<IconFileExcel size={16} />}
 | 
				
			||||||
| 
						 | 
					@ -1054,6 +1060,35 @@ const Timekeeping = () => {
 | 
				
			||||||
          </Table.Tbody>
 | 
					          </Table.Tbody>
 | 
				
			||||||
        </Table>
 | 
					        </Table>
 | 
				
			||||||
      </Box>
 | 
					      </Box>
 | 
				
			||||||
 | 
					      <Modal
 | 
				
			||||||
 | 
					        opened={exportModalOpened}
 | 
				
			||||||
 | 
					        onClose={() => setExportModalOpened(false)}
 | 
				
			||||||
 | 
					        title={
 | 
				
			||||||
 | 
					          <Text pl={'sm'} fw={700} fz={'lg'}>
 | 
				
			||||||
 | 
					            Export
 | 
				
			||||||
 | 
					          </Text>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        size="sm"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <Select
 | 
				
			||||||
 | 
					          label="Option"
 | 
				
			||||||
 | 
					          placeholder="Choose an option"
 | 
				
			||||||
 | 
					          value={exportOption}
 | 
				
			||||||
 | 
					          onChange={(value) => setExportOption(value || 'default')}
 | 
				
			||||||
 | 
					          data={[
 | 
				
			||||||
 | 
					            { value: 'default', label: 'Default' }
 | 
				
			||||||
 | 
					          ]}
 | 
				
			||||||
 | 
					          mb="md"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <Box style={{ display: 'flex', justifyContent: 'flex-end', gap: '10px' }}>
 | 
				
			||||||
 | 
					          <Button variant="outline" onClick={() => setExportModalOpened(false)}>
 | 
				
			||||||
 | 
					            Close
 | 
				
			||||||
 | 
					          </Button>
 | 
				
			||||||
 | 
					          <Button onClick={() => handleExport(exportOption)}>
 | 
				
			||||||
 | 
					            Export
 | 
				
			||||||
 | 
					          </Button>
 | 
				
			||||||
 | 
					        </Box>
 | 
				
			||||||
 | 
					      </Modal>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue