ManActivityTimeCardSheetExport.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. namespace App\Exports;
  3. use Maatwebsite\Excel\Concerns\FromCollection;
  4. use Maatwebsite\Excel\Concerns\WithEvents;
  5. use Maatwebsite\Excel\Concerns\WithStyles;
  6. use Maatwebsite\Excel\Concerns\WithTitle;
  7. use Maatwebsite\Excel\Concerns\WithCustomStartCell;
  8. use Maatwebsite\Excel\Events\AfterSheet;
  9. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  10. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  11. use PhpOffice\PhpSpreadsheet\Style\Border;
  12. use PhpOffice\PhpSpreadsheet\Style\Fill;
  13. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  14. class ManActivityTimeCardSheetExport implements FromCollection, WithEvents, WithStyles, WithCustomStartCell, WithTitle
  15. {
  16. protected $projectName;
  17. protected $data;
  18. protected $year;
  19. public function __construct(string $projectName, array $data, string $year)
  20. {
  21. $this->projectName = $projectName;
  22. $this->data = $data;
  23. $this->year = $year;
  24. }
  25. public function title(): string
  26. {
  27. // Sheet名不能超过31个字符
  28. return mb_substr($this->projectName, 0, 30);
  29. }
  30. public function startCell(): string
  31. {
  32. return 'A6'; // 数据从 A6 开始写入
  33. }
  34. public function collection()
  35. {
  36. return collect($this->data);
  37. }
  38. public function registerEvents(): array
  39. {
  40. return [
  41. AfterSheet::class => function(AfterSheet $event) {
  42. $sheet = $event->sheet->getDelegate();
  43. $lastCol = 'R';
  44. // --- 1. 设置列宽 ---
  45. $widths = [
  46. 'A' => 8, 'B' => 12, 'C' => 10, 'D' => 10, 'E' => 10, 'F' => 10,
  47. 'G' => 12, 'H' => 10, 'I' => 10, 'J' => 12, 'K' => 10, 'L' => 10,
  48. 'M' => 12, 'N' => 10, 'O' => 10, 'P' => 12, 'Q' => 10, 'R' => 10
  49. ];
  50. foreach ($widths as $col => $w) {
  51. $sheet->getColumnDimension($col)->setWidth($w);
  52. }
  53. // --- 2. 第一行:主标题 (宋体 18 加粗) ---
  54. $sheet->mergeCells("A1:{$lastCol}1");
  55. $sheet->setCellValue('A1', "{$this->year}年研发人员研发活动工时占比计算及研发人员费用调整表");
  56. $sheet->getStyle('A1')->applyFromArray([
  57. 'font' => ['name' => '宋体', 'size' => 18, 'bold' => true],
  58. 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
  59. ]);
  60. // --- 3. 第二行:项目名称 (宋体 9 加粗) ---
  61. $sheet->mergeCells("A2:{$lastCol}2");
  62. $sheet->setCellValue('A2', "项目名称:{$this->projectName}");
  63. $sheet->getStyle('A2')->applyFromArray([
  64. 'font' => ['name' => '宋体', 'size' => 9, 'bold' => true],
  65. 'alignment' => ['horizontal' => Alignment::HORIZONTAL_LEFT],
  66. ]);
  67. // --- 4. 第三至五行:表头逻辑 (宋体 11 加粗 自动换行) ---
  68. foreach (['A', 'B', 'C'] as $col) { $sheet->mergeCells("{$col}3:{$col}5"); }
  69. $sheet->setCellValue('A3', "月份"); $sheet->setCellValue('B3', "人员类别"); $sheet->setCellValue('C3', "姓名");
  70. $sheet->mergeCells('D3:F3'); $sheet->setCellValue('D3', '工时占比计算');
  71. $sheet->mergeCells('D4:D5'); $sheet->setCellValue('D4', '应出勤工时');
  72. $sheet->mergeCells('E4:E5'); $sheet->setCellValue('E4', '研发出勤工时');
  73. $sheet->mergeCells('F4:F5'); $sheet->setCellValue('F4', '研发工时占比');
  74. $sheet->mergeCells('G3:L3'); $sheet->setCellValue('G3', '账面归集金额');
  75. $sheet->mergeCells('G4:I4'); $sheet->setCellValue('G4', '归集总额');
  76. $sheet->setCellValue('G5', '工资总额'); $sheet->setCellValue('H5', '社保'); $sheet->setCellValue('I5', '公积金');
  77. $sheet->mergeCells('J4:L4'); $sheet->setCellValue('J4', '其中属于研发活动期间金额');
  78. $sheet->setCellValue('J5', '工资总额'); $sheet->setCellValue('K5', '社保'); $sheet->setCellValue('L5', '公积金');
  79. $sheet->mergeCells('M3:O4'); $sheet->setCellValue('M3', '研发活动期间的确定金额');
  80. $sheet->setCellValue('M5', '工资总额'); $sheet->setCellValue('N5', '社保'); $sheet->setCellValue('O5', '公积金');
  81. $sheet->mergeCells('P3:R4'); $sheet->setCellValue('P3', '加计调整金额');
  82. $sheet->setCellValue('P5', '工资总额'); $sheet->setCellValue('Q5', '社保'); $sheet->setCellValue('R5', '公积金');
  83. // 应用三到五行样式
  84. $sheet->getStyle("A3:{$lastCol}5")->applyFromArray([
  85. 'font' => ['name' => '宋体', 'size' => 11, 'bold' => true],
  86. 'alignment' => [
  87. 'wrapText' => true,
  88. 'horizontal' => Alignment::HORIZONTAL_CENTER,
  89. 'vertical' => Alignment::VERTICAL_CENTER
  90. ],
  91. ]);
  92. // --- 5. 染色逻辑 ---
  93. $highestRow = $sheet->getHighestRow();
  94. for ($row = 6; $row <= $highestRow; $row++) {
  95. $cellA = $sheet->getCell("A{$row}")->getValue();
  96. if ($cellA === '小计:') {
  97. $sheet->getStyle("A{$row}:{$lastCol}{$row}")->getFill()
  98. ->setFillType(Fill::FILL_SOLID)->getStartColor()->setRGB('F4B084');
  99. } elseif ($cellA === '合计') {
  100. $sheet->getStyle("A{$row}:{$lastCol}{$row}")->getFill()
  101. ->setFillType(Fill::FILL_SOLID)->getStartColor()->setRGB('FFFF00');
  102. }
  103. }
  104. },
  105. ];
  106. }
  107. public function styles(Worksheet $sheet)
  108. {
  109. $highestRow = $sheet->getHighestRow();
  110. $lastCol = 'R';
  111. return [
  112. // 全表通用对齐和边框
  113. "A1:{$lastCol}{$highestRow}" => [
  114. 'borders' => [
  115. 'allBorders' => ['borderStyle' => Border::BORDER_THIN],
  116. ],
  117. 'alignment' => [
  118. 'vertical' => Alignment::VERTICAL_CENTER,
  119. ],
  120. ],
  121. // 数据行:宋体 10,居中,不加粗
  122. "A6:{$lastCol}{$highestRow}" => [
  123. 'font' => [
  124. 'name' => '宋体',
  125. 'size' => 10,
  126. 'bold' => false
  127. ],
  128. 'alignment' => [
  129. 'horizontal' => Alignment::HORIZONTAL_CENTER,
  130. ],
  131. ]
  132. ];
  133. }
  134. }