ProjectDepreciationSheetExport.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 ProjectDepreciationSheetExport implements WithEvents, WithTitle
  11. {
  12. protected $groupKey;
  13. protected $projectName;
  14. protected $monthsData;
  15. public function __construct($groupKey, $projectName, $monthsData)
  16. {
  17. $this->groupKey = $groupKey;
  18. $this->projectName = $projectName;
  19. $this->monthsData = $monthsData;
  20. }
  21. public function title(): string { return $this->groupKey; }
  22. public function registerEvents(): array
  23. {
  24. return [
  25. AfterSheet::class => function (AfterSheet $event) {
  26. $sheet = $event->sheet->getDelegate();
  27. $currentRow = 1;
  28. // --- 关键:预先设置列宽 ---
  29. $sheet->getColumnDimension('A')->setWidth(6);
  30. $sheet->getColumnDimension('B')->setWidth(25);
  31. $sheet->getColumnDimension('J')->setWidth(15);
  32. $sheet->getColumnDimension('L')->setWidth(12); // 给 L 列足够的空间
  33. foreach ($this->monthsData as $month => $items) {
  34. // 记录本月表格的起始行
  35. $tableStartRow = $currentRow;
  36. // 1. 标题 (A-J)
  37. $sheet->mergeCells("A{$currentRow}:J{$currentRow}");
  38. $displayYear = date('Y', strtotime($month));
  39. $sheet->setCellValue("A{$currentRow}", "{$displayYear}年度研发项目折旧费用调整表");
  40. $sheet->getStyle("A{$currentRow}")->getFont()->setBold(true)->setSize(16);
  41. $sheet->getStyle("A{$currentRow}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  42. $currentRow++;
  43. // 2. 项目名称与单位 (A-J)
  44. $sheet->setCellValue("A{$currentRow}", "研发项目名称:{$this->projectName}");
  45. $sheet->mergeCells("H{$currentRow}:J{$currentRow}");
  46. $sheet->setCellValue("H{$currentRow}", "单位:元以下角分");
  47. $sheet->getStyle("H{$currentRow}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
  48. $currentRow++;
  49. // 3. 表头 (A-J)
  50. $headerRow1 = $currentRow;
  51. $sheet->mergeCells("A{$currentRow}:A" . ($currentRow + 1)); $sheet->setCellValue("A{$currentRow}", "序号");
  52. $sheet->mergeCells("B{$currentRow}:B" . ($currentRow + 1)); $sheet->setCellValue("B{$currentRow}", "设备名称");
  53. $sheet->mergeCells("C{$currentRow}:E{$currentRow}"); $sheet->setCellValue("C{$currentRow}", "设备工时");
  54. $sheet->mergeCells("F{$currentRow}:I{$currentRow}"); $sheet->setCellValue("F{$currentRow}", "设备折旧");
  55. $sheet->mergeCells("J{$currentRow}:J" . ($currentRow + 1)); $sheet->setCellValue("J{$currentRow}", "加计调整\n金额");
  56. $currentRow++;
  57. $sheet->setCellValue("C{$currentRow}", "设备总工时");
  58. $sheet->setCellValue("D{$currentRow}", "其中本项目\n工时");
  59. $sheet->setCellValue("E{$currentRow}", "研发活动工\n时占比(%)");
  60. $sheet->setCellValue("F{$currentRow}", "原值");
  61. $sheet->setCellValue("G{$currentRow}", "折旧额");
  62. $sheet->setCellValue("H{$currentRow}", "确定的本\n项目折旧额");
  63. $sheet->setCellValue("I{$currentRow}", "备注说明");
  64. $currentRow++;
  65. // 4. 数据行
  66. $dataRowsCount = count($items);
  67. foreach ($items as $index => $item) {
  68. $sheet->setCellValue("A{$currentRow}", $index + 1);
  69. $sheet->setCellValue("B{$currentRow}", $item['name'] ?? '');
  70. $sheet->setCellValue("C{$currentRow}", $item['total_hours'] ?? 0);
  71. $sheet->setCellValue("D{$currentRow}", $item['project_hours'] ?? 0);
  72. $sheet->setCellValue("E{$currentRow}", ($item['ratio'] ?? 0) . '%');
  73. $sheet->setCellValue("F{$currentRow}", $item['original_value'] ?? 0);
  74. $sheet->setCellValue("G{$currentRow}", $item['depreciation'] ?? 0);
  75. $sheet->setCellValue("H{$currentRow}", $item['confirmed_depreciation'] ?? 0);
  76. $sheet->setCellValue("I{$currentRow}", "");
  77. $sheet->setCellValue("J{$currentRow}", $item['adjust_amount'] ?? 0);
  78. // --- 核心修正:确保月份在 L 列显示 ---
  79. // 我们把月份放在数据行的第一行对应的 L 列
  80. if ($index === 0) {
  81. $sheet->setCellValue("L{$currentRow}", $month . "月");
  82. // 样式:宋体、加粗、靠左对齐
  83. $sheet->getStyle("L{$currentRow}")->getFont()->setName('SimSun')->setBold(true)->setSize(12);
  84. $sheet->getStyle("L{$currentRow}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
  85. }
  86. $currentRow++;
  87. }
  88. // 5. 合计行
  89. $sheet->setCellValue("A{$currentRow}", "合计");
  90. $sheet->mergeCells("A{$currentRow}:B{$currentRow}");
  91. // 这里可以填充合计逻辑...
  92. $currentRow++;
  93. // 6. 备注
  94. $sheet->mergeCells("A{$currentRow}:J{$currentRow}");
  95. $sheet->setCellValue("A{$currentRow}", "备注:按研发项目的研发活动工作使用情况记录等相关证据资料...");
  96. $sheet->getStyle("A{$currentRow}")->getFont()->setSize(9);
  97. $currentRow += 2; // 间隔
  98. // --- 7. 样式应用:仅针对 A-J 列加边框 ---
  99. $tableRange = "A{$tableStartRow}:J" . ($currentRow - 2);
  100. $sheet->getStyle($tableRange)->getFont()->setName('SimSun');
  101. $sheet->getStyle("A" . ($tableStartRow + 2) . ":J" . ($currentRow - 2))->applyFromArray([
  102. 'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN]],
  103. ]);
  104. // 居中对齐
  105. $sheet->getStyle("A{$tableStartRow}:J" . ($currentRow - 2))->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
  106. }
  107. },
  108. ];
  109. }
  110. }