ExcelHelper.php 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace App\Helpers;
  3. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  4. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  5. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  6. class ExcelHelper
  7. {
  8. public static function copyRows( Worksheet $sheet, $srcRange, $dstCell, Worksheet $destSheet = null): void
  9. {
  10. if( !isset($destSheet)) {
  11. $destSheet = $sheet;
  12. }
  13. if( !preg_match('/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/', $srcRange, $srcRangeMatch) ) {
  14. // Invalid src range
  15. return;
  16. }
  17. if( !preg_match('/^([A-Z]+)(\d+)$/', $dstCell, $destCellMatch) ) {
  18. // Invalid dest cell
  19. return;
  20. }
  21. $srcColumnStart = $srcRangeMatch[1];
  22. $srcRowStart = $srcRangeMatch[2];
  23. $srcColumnEnd = $srcRangeMatch[3];
  24. $srcRowEnd = $srcRangeMatch[4];
  25. $destColumnStart = $destCellMatch[1];
  26. $destRowStart = $destCellMatch[2];
  27. $srcColumnStart = Coordinate::columnIndexFromString($srcColumnStart);
  28. $srcColumnEnd = Coordinate::columnIndexFromString($srcColumnEnd);
  29. $destColumnStart = Coordinate::columnIndexFromString($destColumnStart);
  30. $rowCount = 0;
  31. for ($row = $srcRowStart; $row <= $srcRowEnd; $row++) {
  32. $colCount = 0;
  33. for ($col = $srcColumnStart; $col <= $srcColumnEnd; $col++) {
  34. $cell = $sheet->getCell([$col, $row]);
  35. $style = $sheet->getStyle([$col, $row]);
  36. $dstCell = Coordinate::stringFromColumnIndex($destColumnStart + $colCount) . (string)((int)$destRowStart + (int)$rowCount);
  37. $destSheet->setCellValue($dstCell, $cell->getValue());
  38. $destSheet->duplicateStyle($style, $dstCell);
  39. // Set width of column, but only once per column
  40. if ($rowCount === 0) {
  41. $w = $sheet->getColumnDimensionByColumn($col)->getWidth();
  42. $destSheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setAutoSize(false);
  43. $destSheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setWidth($w);
  44. }
  45. $colCount++;
  46. }
  47. $h = $sheet->getRowDimension($row)->getRowHeight();
  48. $destSheet->getRowDimension((int)$destRowStart + $rowCount)->setRowHeight($h);
  49. $rowCount++;
  50. }
  51. foreach ($sheet->getMergeCells() as $mergeCell) {
  52. $mc = explode(":", $mergeCell);
  53. $mergeColSrcStart = Coordinate::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[0]));
  54. $mergeColSrcEnd = Coordinate::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[1]));
  55. $mergeRowSrcStart = ((int)preg_replace("/[A-Z]*/", "", $mc[0]));
  56. $mergeRowSrcEnd = ((int)preg_replace("/[A-Z]*/", "", $mc[1]));
  57. $relativeColStart = $mergeColSrcStart - $srcColumnStart;
  58. $relativeColEnd = $mergeColSrcEnd - $srcColumnStart;
  59. $relativeRowStart = $mergeRowSrcStart - $srcRowStart;
  60. $relativeRowEnd = $mergeRowSrcEnd - $srcRowStart;
  61. if (0 <= $mergeRowSrcStart && $mergeRowSrcStart >= $srcRowStart && $mergeRowSrcEnd <= $srcRowEnd) {
  62. $targetColStart = Coordinate::stringFromColumnIndex($destColumnStart + $relativeColStart);
  63. $targetColEnd = Coordinate::stringFromColumnIndex($destColumnStart + $relativeColEnd);
  64. $targetRowStart = (int)$destRowStart + $relativeRowStart;
  65. $targetRowEnd = (int)$destRowStart + $relativeRowEnd;
  66. $merge = (string)$targetColStart . (string)($targetRowStart) . ":" . (string)$targetColEnd . (string)($targetRowEnd);
  67. //Merge target cells
  68. $destSheet->mergeCells($merge);
  69. }
  70. }
  71. }
  72. public static function copyStyleXFCollection(Spreadsheet $sourceSheet, Spreadsheet $destSheet) {
  73. $collection = $sourceSheet->getCellXfCollection();
  74. foreach ($collection as $key => $item) {
  75. $destSheet->addCellXf($item);
  76. }
  77. }
  78. }