ManMonthlyWorkHourSheetExport.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. namespace App\Exports;
  3. use Maatwebsite\Excel\Concerns\WithEvents;
  4. use Maatwebsite\Excel\Concerns\WithTitle;
  5. use Maatwebsite\Excel\Events\AfterSheet;
  6. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  7. use PhpOffice\PhpSpreadsheet\Style\Border;
  8. use PhpOffice\PhpSpreadsheet\Style\Borders;
  9. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  10. class ManMonthlyWorkHourSheetExport implements WithEvents, WithTitle
  11. {
  12. protected $monthName;
  13. protected $data;
  14. protected $daysInMonth;
  15. protected $company_name;
  16. public function __construct(string $monthName, array $data, int $daysInMonth, string $company_name)
  17. {
  18. $this->monthName = $monthName;
  19. $this->data = $data;
  20. $this->daysInMonth = $daysInMonth;
  21. $this->company_name = $company_name;
  22. }
  23. public function title(): string
  24. {
  25. return $this->monthName;
  26. }
  27. public function registerEvents(): array
  28. {
  29. return [
  30. AfterSheet::class => function (AfterSheet $event) {
  31. $sheet = $event->sheet->getDelegate();
  32. // 计算最大列(项目B + 姓名C + 天数)
  33. $totalColNum = 2 + $this->daysInMonth;
  34. $highestColumn = Coordinate::stringFromColumnIndex($totalColNum);
  35. // --- 1. 第一行:主标题 ---
  36. $sheet->mergeCells("A1:{$highestColumn}1");
  37. $sheet->setCellValue('A1', "{$this->monthName}研发人员工时统计表");
  38. $sheet->getStyle('A1')->getFont()->setSize(14);
  39. $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  40. // --- 2. 第二行:单位行 ---
  41. $sheet->mergeCells("A2:{$highestColumn}2");
  42. $sheet->setCellValue('A2', "单位:" . $this->company_name);
  43. $sheet->getStyle('A2')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
  44. // --- 3. 第三行表头设置 ---
  45. // (1) A3: 项目名称 (独立单元格)
  46. $sheet->setCellValue('A3', "项目名称");
  47. $sheet->getColumnDimension('A')->setWidth(14);
  48. // (2) B3: 人员名称/日期 (斜线分割单元格)
  49. $sheet->setCellValue('B3', " 日期 \n人员名称");
  50. $sheet->getStyle('B3')->getAlignment()->setWrapText(true);
  51. $sheet->getStyle('B3')->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
  52. $sheet->getStyle('B3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
  53. $sheet->getColumnDimension('B')->setWidth(16);
  54. // 绘制 B3 斜线
  55. $sheet->getStyle('B3')->getBorders()->applyFromArray([
  56. 'diagonal' => [
  57. 'borderStyle' => Border::BORDER_THIN,
  58. 'color' => ['rgb' => '000000'],
  59. ],
  60. ]);
  61. $sheet->getStyle('B3')->getBorders()->setDiagonalDirection(Borders::DIAGONAL_DOWN);
  62. // (3) C3 往后: 动态日期 (1, 2, 3...)
  63. for ($day = 1; $day <= $this->daysInMonth; $day++) {
  64. $colLetter = Coordinate::stringFromColumnIndex($day + 2); // 从 C 列开始
  65. $sheet->setCellValue($colLetter . '3', $day);
  66. $sheet->getColumnDimension($colLetter)->setWidth(8);
  67. }
  68. // 设置第三行行高
  69. $sheet->getRowDimension(3)->setRowHeight(50);
  70. // --- 4. 写入数据行 (从第4行开始) ---
  71. $dataStartRow = 4;
  72. if (!empty($this->data)) {
  73. foreach ($this->data as $rowIndex => $row) {
  74. $currentRow = $dataStartRow + $rowIndex;
  75. foreach ($row as $colIndex => $cellValue) {
  76. $colLetter = Coordinate::stringFromColumnIndex($colIndex + 1);
  77. $sheet->setCellValue($colLetter . $currentRow, $cellValue);
  78. }
  79. }
  80. }
  81. // --- 5. 全局样式微调 ---
  82. $highestRow = $sheet->getHighestRow();
  83. // 1. 设置工时数据区域的格式为数字,并保留两位小数
  84. $dataRange = "C4:{$highestColumn}{$highestRow}";
  85. $sheet->getStyle($dataRange)->getNumberFormat()->setFormatCode('#,##0.00');
  86. // 或者用 NumberFormat::FORMAT_NUMBER_00
  87. // 所有单元格垂直居中
  88. $sheet->getStyle("A1:{$highestColumn}{$highestRow}")->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
  89. // 表头及日期数据水平居中 (排除 A3 和 B3)
  90. $sheet->getStyle("A3:{$highestColumn}{$highestRow}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  91. $sheet->getStyle('B3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); // 斜线格保持左对齐
  92. // 添加表格边框 (从 A3 开始)
  93. $sheet->getStyle("A3:{$highestColumn}{$highestRow}")->applyFromArray([
  94. 'borders' => [
  95. 'allBorders' => [
  96. 'borderStyle' => Border::BORDER_THIN,
  97. ],
  98. ],
  99. ]);
  100. },
  101. ];
  102. }
  103. }