ManMonthlyWorkHourSheetExport.php 5.2 KB

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