94 lines
3.9 KiB
PHP
94 lines
3.9 KiB
PHP
<?php
|
|
namespace App\Helpers;
|
|
|
|
use Exception;
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
|
|
class ExcelMergeHelper
|
|
{
|
|
/**
|
|
* Merge multiple Excel files into a single spreadsheet.
|
|
*
|
|
* @param array $filesToMerge Array of files to merge.
|
|
* @param string $outputPath Path to save the merged file.
|
|
* @return bool True if merge successful, false otherwise.
|
|
*/
|
|
public static function mergeExcelFiles(array $filesToMerge, string $outputPath): bool
|
|
{
|
|
try {
|
|
// Validate input: If no files are provided, throw an error.
|
|
if (empty($filesToMerge)) {
|
|
throw new Exception("No files provided for merging");
|
|
}
|
|
|
|
// Initialize the base spreadsheet (starting with null, will be created with the first file)
|
|
$spreadsheet = null;
|
|
|
|
// Loop through the files to merge
|
|
foreach ($filesToMerge as $filePath => $sheetsToMerge) {
|
|
// Load the current file
|
|
$currentSpreadsheet = IOFactory::load($filePath);
|
|
|
|
// Debugging: Log the number of sheets in the current file
|
|
error_log("File: $filePath has " . $currentSpreadsheet->getSheetCount() . " sheets.");
|
|
|
|
// If this is the first file, initialize the base spreadsheet
|
|
if ($spreadsheet === null) {
|
|
$spreadsheet = $currentSpreadsheet;
|
|
|
|
// If specific sheets are provided for the first file, remove the others
|
|
if (!is_null($sheetsToMerge) && !empty($sheetsToMerge)) {
|
|
$sheetCount = $spreadsheet->getSheetCount();
|
|
for ($i = $sheetCount - 1; $i >= 0; $i--) {
|
|
if (!in_array($i, $sheetsToMerge)) {
|
|
$spreadsheet->removeSheetByIndex($i);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// If we are not working with the first file, we need to merge specified sheets
|
|
if (is_null($sheetsToMerge) || empty($sheetsToMerge)) {
|
|
// If no specific sheets, merge all sheets
|
|
$sheetsToMerge = range(0, $currentSpreadsheet->getSheetCount() - 1);
|
|
}
|
|
|
|
// Merge the specified sheets from the current file
|
|
foreach ($sheetsToMerge as $sheetIndex) {
|
|
// Check if sheet index is within bounds
|
|
if ($sheetIndex < 0 || $sheetIndex >= $currentSpreadsheet->getSheetCount()) {
|
|
throw new Exception("Invalid sheet index $sheetIndex in file $filePath");
|
|
}
|
|
|
|
// Retrieve the sheet to copy
|
|
$sheetToCopy = $currentSpreadsheet->getSheet($sheetIndex);
|
|
|
|
// Handle sheet name collision by renaming the sheet with a counter
|
|
$baseName = $sheetToCopy->getTitle();
|
|
$sheetName = $baseName;
|
|
$counter = 1;
|
|
while ($spreadsheet->sheetNameExists($sheetName)) {
|
|
$sheetName = $baseName . '_merged_' . $counter;
|
|
$counter++;
|
|
}
|
|
$sheetToCopy->setTitle($sheetName);
|
|
|
|
// Clone and add the sheet to the base spreadsheet
|
|
$spreadsheet->addSheet(clone $sheetToCopy);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save the merged file
|
|
$writer = new Xlsx($spreadsheet);
|
|
$writer->save($outputPath);
|
|
|
|
return true; // Return true if merge was successful
|
|
} catch (Exception $e) {
|
|
// Log the error (optional) and return false on failure
|
|
error_log("Excel Merge Error: " . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
}
|