json); // Get counter values for report numbers $reportNoCounter = get_counter("Construction_Paint_Log"); $constructionReportNoCounter = get_counter("Construction_Report"); // Get patterns from settings $reportNoPattern = setting('construction_paint_log_pattern'); $constructionReportNoPattern = setting('construction_report_pattern'); // Generate report numbers $reportNo = str_replace("{number}", $reportNoCounter, $reportNoPattern); $constructionReportNo = str_replace("{number}", $constructionReportNoCounter, $constructionReportNoPattern); // Update report numbers in the database foreach($data as $item) { $updateData = [ "report_no" => $reportNo, "construction_report_no" => $constructionReportNo, 'updated_at' => now() ]; db("construction_paint_logs") ->where("id", $item['id']) ->update($updateData); } // Load Excel template $spreadsheet = IOFactory::load('storage/documents/' . $documentInfo->files); $sheet = $spreadsheet->getActiveSheet(); $templateRowNo = 16; $startRow = $templateRowNo; // Get template row cells and formulas $templateRowCells = []; $templateFormulas = []; foreach ($sheet->getRowIterator($startRow)->current()->getCellIterator() as $cell) { $templateRowCells[] = $cell->getValue(); if ($cell->isFormula()) { $colIndex = $cell->getColumn(); $templateFormulas[$colIndex] = $cell->getValue(); } } // Get merged cells in template row $mergedCells = []; foreach ($sheet->getMergeCells() as $mergeRange) { if (preg_match('/^\D*'.$startRow.'$/', explode(':', $mergeRange)[0])) { $mergedCells[] = $mergeRange; } } // Process each selected record foreach($data as $index => $item) { // Get full record data $record = db("construction_paint_logs")->where("id", $item['id'])->first(); // Insert new row $sheet->insertNewRowBefore($startRow + 1, 1); $newRow = $sheet->getRowIterator($startRow + 1)->current(); // Copy template values and replace placeholders $cellIndex = 0; foreach ($newRow->getCellIterator() as $newCell) { $newCellValue = $templateRowCells[$cellIndex]; $colLetter = $newCell->getColumn(); if (isset($templateFormulas[$colLetter])) { // Handle formulas $formula = $templateFormulas[$colLetter]; $rowOffset = $index + 1; // Update formula references $updatedFormula = preg_replace_callback( '/([A-Z]+)(\d+)/', function($matches) use ($rowOffset) { $col = $matches[1]; $row = intval($matches[2]); return $col . ($row + $rowOffset); }, $formula ); $newCell->setValue($updatedFormula); } else { // Replace placeholders with actual values foreach((array)$record as $field => $value) { if (is_string($value)) { $newCellValue = str_replace('{'.$field.'}', $value, $newCellValue); } } $newCell->setValue($newCellValue); } $cellIndex++; } // Apply merged cells to new row foreach ($mergedCells as $mergeRange) { $adjustedMergeRange = preg_replace_callback( '/\d+/', function($matches) use ($startRow) { return $matches[0] + 1; }, $mergeRange ); $sheet->mergeCells($adjustedMergeRange); } $startRow++; } // Remove template row $sheet->removeRow(intval($templateRowNo)); // Save Excel file $fileName = $reportNo . '.xlsx'; $documentPath = $documentInfo->kid; $path = "storage/documents/$documentPath/$fileName"; if (!file_exists(dirname($path))) { mkdir(dirname($path), 0777, true); } try { $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save($path); } catch (\Exception $e) { Log::error('Error saving Excel file', [ 'error' => $e->getMessage(), 'file_path' => $path ]); throw $e; } // Convert to PDF $pdfResult = xlsx_to_pdf_legacy($path, "storage/documents/$documentPath"); echo $pdfResult; $endTime = microtime(true); } catch (\Exception $e) { Log::error('Fatal error in PDF generation process', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); throw $e; } ?>