now()->format('Y-m-d H:i:s')]); logProcessInfo('PDF generation process started', [ 'request_data' => $_POST, 'user' => auth()?->user()?->name ?? 'System' ]); $templateRowNo = post("templateRowNo"); $repeatedRows = post("repeatedRows"); $isMultipleMode = post("isMultipleMode") == "true"; $documentInfo = document_template(post("documentId")); Log::debug('📄 [START] Template settings loaded', ['timestamp' => now()->format('Y-m-d H:i:s')]); logProcessInfo('Template settings loaded', [ 'template_row_no' => $templateRowNo, 'is_multiple_mode' => $isMultipleMode, 'document_info' => $documentInfo->kid ]); $sqlCodeMaster = post("sqlCodeMaster"); $sqlCodeDetail = post("sqlCodeDetail"); $j = j($documentInfo->json); $temperatures = j(setting("temperatures")); if(postisset("rowData")) { $resultMaster[] = $_POST['rowData']; Log::debug('🟢 [START] Using provided row data', ['timestamp' => now()->format('Y-m-d H:i:s')]); logProcessInfo('Using provided row data'); Log::debug('🟢 [END] Using provided row data', ['timestamp' => now()->format('Y-m-d H:i:s')]); } else { Log::debug('🟢 [START] Executing master SQL query', ['timestamp' => now()->format('Y-m-d H:i:s')]); logProcessInfo('Executing master SQL query'); $resultMaster = ($sqlCodeMaster && stripos(trim($sqlCodeMaster), 'SELECT') === 0) ? DB::select($sqlCodeMaster) : []; logProcessInfo('Master SQL query completed', [ 'rows_count' => count($resultMaster) ]); Log::debug('🟢 [END] Executing master SQL query', ['timestamp' => now()->format('Y-m-d H:i:s')]); } // Master verisindeki tarih alanlarını formatla foreach($resultMaster as &$master) { $master = formatDateColumns($master); } // Batch işleme için veriyi böl $batchSize = 100; // Her batch'te 100 satır işle (performans için artırıldı) $totalCount = count($resultMaster); $processedCount = 0; logProcessInfo('Starting batch processing', [ 'total_records' => $totalCount, 'batch_size' => $batchSize, 'estimated_batches' => ceil($totalCount / $batchSize) ]); for ($batchIndex = 0; $batchIndex < ceil($totalCount / $batchSize); $batchIndex++) { $batchStart = $batchIndex * $batchSize; $batchEnd = min($batchStart + $batchSize, $totalCount); $batchData = array_slice($resultMaster, $batchStart, $batchSize, true); // logProcessInfo('Processing batch', [ // 'batch_index' => $batchIndex + 1, // 'batch_start' => $batchStart, // 'batch_end' => $batchEnd, // 'batch_count' => count($batchData), // 'memory_before_batch' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); foreach($batchData AS $masterIndex => $master) { $processingStart = microtime(true); $processedCount++; // Progress hesapla $progressPercent = round(($processedCount / $totalCount) * 100, 2); //Log::debug('🔄 [START] Processing master row', ['index' => $masterIndex, 'timestamp' => now()->format('Y-m-d H:i:s')]); /* logProcessInfo('Processing master row', [ 'index' => $masterIndex, 'processed_count' => $processedCount, 'total_masters' => $totalCount, 'progress_percent' => $progressPercent, 'batch_index' => $batchIndex + 1, 'memory_current' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' ]); */ // Her 500 kayıtta bir progress göster (performans için artırıldı) if ($processedCount % 500 == 0 || $processedCount == 1) { echo "Progress: {$processedCount}/{$totalCount} ({$progressPercent}%)\n"; flush(); // Output buffer'ı temizle } try { // Load your Excel template file // Log::debug('📥 [START] Load Excel template', ['master_index' => $masterIndex, 'timestamp' => now()->format('Y-m-d H:i:s')]); $templatePath = 'storage/documents/' . $documentInfo->files; if (!file_exists($templatePath)) { throw new Exception("Template file not found: {$templatePath}"); } $spreadsheet = IOFactory::load($templatePath); // logProcessInfo('Excel template loaded successfully', [ // 'master_index' => $masterIndex, // 'template_path' => $templatePath, // 'memory_after_load' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Log::debug('📥 [END] Load Excel template', ['master_index' => $masterIndex, 'timestamp' => now()->format('Y-m-d H:i:s')]); // Spreadsheet türünü kontrol et // echo "Yüklenen Excel türü: " . get_class($spreadsheet) . "\n"; $sheet = $spreadsheet->getActiveSheet(); $fileName = post("fileNameTemplate"); $fileName = replacePlaceholdersFileName($fileName, $master); // Dosya adında da converter-map çevirisini uygula $fileName = converterMapStringReplacer($fileName); // İlk sonucu al (birden fazla kayıt varsa foreach kullanabilirsiniz) $masterData = is_array($master) ? $master : (array)$master; // Başlangıçta boş bir replacements dizisi tanımla $replacements = []; try { // logProcessInfo('Starting workPermitReplacerExcel2 function call', [ // 'function' => 'workPermitReplacerExcel2', // 'spreadsheet_type' => get_class($spreadsheet), // 'document_id' => $documentInfo->kid, // 'master_data_keys' => array_keys((array)$master), // 'replacer_type' => 'replacer', // 'memory_before' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); $result = workPermitReplacerExcel2($spreadsheet, $master, $documentInfo, "replacer"); // logProcessInfo('workPermitReplacerExcel2 function completed', [ // 'result_type' => is_null($result) ? 'NULL' : (is_object($result) ? get_class($result) : gettype($result)), // 'is_valid_spreadsheet' => ($result !== null && $result instanceof PhpOffice\PhpSpreadsheet\Spreadsheet), // 'memory_after' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Eğer fonksiyon null döndürmüşse, orijinal spreadsheet'i kullan if ($result !== null && $result instanceof PhpOffice\PhpSpreadsheet\Spreadsheet) { // logProcessInfo('Using replacement result spreadsheet', [ // 'action' => 'spreadsheet_replaced', // 'new_spreadsheet_type' => get_class($result) // ]); $spreadsheet = $result; } else { // logProcessInfo('Using original spreadsheet - replacement failed or returned invalid result', [ // 'action' => 'keep_original_spreadsheet', // 'result_received' => is_null($result) ? 'NULL' : gettype($result), // 'warning' => 'workPermitReplacerExcel2 did not return valid spreadsheet' // ], 'warning'); } // Converter-map replacement'i uygula try { // logProcessInfo('Starting converterMapReplacer function call', [ // 'function' => 'converterMapReplacer', // 'spreadsheet_type' => get_class($spreadsheet), // 'replacer_type' => 'replacer', // 'memory_before' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); $converterResult = converterMapReplacer($spreadsheet, "replacer"); // logProcessInfo('converterMapReplacer function completed', [ // 'result_type' => is_null($converterResult) ? 'NULL' : (is_object($converterResult) ? get_class($converterResult) : gettype($converterResult)), // 'is_valid_spreadsheet' => ($converterResult !== null && $converterResult instanceof PhpOffice\PhpSpreadsheet\Spreadsheet), // 'memory_after' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Eğer fonksiyon geçerli bir spreadsheet döndürmüşse, onu kullan if ($converterResult !== null && $converterResult instanceof PhpOffice\PhpSpreadsheet\Spreadsheet) { // logProcessInfo('Using converter map replacement result spreadsheet', [ // 'action' => 'spreadsheet_replaced_with_converter_map', // 'new_spreadsheet_type' => get_class($converterResult) // ]); $spreadsheet = $converterResult; } else { // logProcessInfo('Using original spreadsheet - converter map replacement failed or returned invalid result', [ // 'action' => 'keep_original_spreadsheet_after_converter_map', // 'result_received' => is_null($converterResult) ? 'NULL' : gettype($converterResult), // 'warning' => 'converterMapReplacer did not return valid spreadsheet' // ], 'warning'); } } catch (\Throwable $th) { // logProcessInfo('Critical error in converterMapReplacer', [ // 'error_type' => get_class($th), // 'error_message' => $th->getMessage(), // 'error_file' => $th->getFile(), // 'error_line' => $th->getLine(), // 'error_code' => $th->getCode(), // 'function_context' => 'converterMapReplacer', // 'document_id' => $documentInfo->kid ?? 'unknown', // 'master_index' => $masterIndex ?? 'unknown', // 'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB', // 'stack_trace' => $th->getTraceAsString() // ], 'error'); } } catch (\Throwable $th) { // logProcessInfo('Critical error in workPermitReplacerExcel2', [ // 'error_type' => get_class($th), // 'error_message' => $th->getMessage(), // 'error_file' => $th->getFile(), // 'error_line' => $th->getLine(), // 'error_code' => $th->getCode(), // 'function_context' => 'workPermitReplacerExcel2', // 'document_id' => $documentInfo->kid ?? 'unknown', // 'master_index' => $masterIndex ?? 'unknown', // 'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB', // 'stack_trace' => $th->getTraceAsString() // ], 'error'); } // Spreadsheet türünü tekrar kontrol et // echo "İşlemden sonraki Excel türü: " . (is_object($spreadsheet) ? get_class($spreadsheet) : gettype($spreadsheet)) . "\n"; // Master verisinden placeholder değerleri oluştur foreach($masterData AS $field => $value) { $replacements['{'.$field.'}'] = $value; } // Sıcaklık değerlerini hesapla ve placeholderlara ekle if (isset($masterData['welding_date']) && isset($masterData['type_of_joint'])) { $tempData = $temperatures[date("z", strtotime($masterData['welding_date']))]; if ($masterData['type_of_joint'] == "S") { $thisTempData = $tempData['shop_ambient']; $thisTempData2 = $tempData['temp_material_shop']; } else { $thisTempData = $tempData['field_ambient']; $thisTempData2 = $tempData['temp_material_field']; } // Sıcaklık placeholder'larını ekle $replacements['{temp_data_ambient}'] = "{$masterData['welding_date']} \n $thisTempData °С"; $replacements['{temp_data_material}'] = "{$masterData['welding_date']} \n $thisTempData2 °С"; } foreach ($sheet->getRowIterator() as $row) { foreach ($row->getCellIterator() as $cell) { $cellValue = $cell->getValue(); if (is_string($cellValue)) { foreach ($replacements as $placeholder => $replacement) { if (strpos($cellValue, $placeholder) !== false) { $newValue = str_replace($placeholder, $replacement, $cellValue); $cell->setValue($newValue); } } // Hücre değerinde converter-map çevirisini de uygula $originalCellValue = $cell->getValue(); if (is_string($originalCellValue)) { $convertedValue = converterMapStringReplacer($originalCellValue); if ($convertedValue !== $originalCellValue) { $cell->setValue($convertedValue); } } } } } // Regex ile SQL'deki bind parametrelerini yakala (örn. :iso_number, :joint_no) preg_match_all('/:\w+/', $sqlCodeDetail, $matches); $params = []; // Parametreleri dolaş ve masterData'daki karşılık gelen anahtarlarla eşleştir foreach ($matches[0] as $param) { // ":" işaretini kaldır (örneğin, :iso_number => iso_number) $paramName = ltrim($param, ':'); // Master verisinden bu parametreye karşılık gelen değeri al if (array_key_exists($paramName, $masterData)) { $params[$paramName] = $masterData[$paramName]; } else { throw new Exception("Master sorgusunda {$paramName} bulunamadı."); } } // Detail sorgusunu parametrelerle çalıştır $resultDetail = []; if (!empty($sqlCodeDetail)) { // logProcessInfo('Executing detail SQL query', [ // 'master_index' => $masterIndex, // 'sql_params' => $params, // 'memory_before_query' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); try { $resultDetail = DB::select($sqlCodeDetail, $params); // logProcessInfo('Detail SQL query completed', [ // 'master_index' => $masterIndex, // 'detail_count' => count($resultDetail), // 'memory_after_query' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Detail verisindeki tarih alanlarını formatla foreach($resultDetail as &$detail) { $detail = formatDateColumns($detail); } } catch (\Exception $e) { // logProcessInfo('Error in detail SQL query', [ // 'master_index' => $masterIndex, // 'error' => $e->getMessage(), // 'sql_params' => $params // ], 'error'); throw $e; } } else { // logProcessInfo('No detail SQL query provided', [ // 'master_index' => $masterIndex // ]); } if(!empty($resultDetail)) { if($isMultipleMode && !empty($repeatedRows)) { // Multiple repeated rows işleme $repeatedRowsArray = json_decode($repeatedRows, true); // logProcessInfo('Processing multiple repeated rows', [ // 'repeated_rows_count' => count($repeatedRowsArray) // ]); // Detail verilerini section'lara göre grupla $sectionedDetails = []; foreach($resultDetail as $detail) { // SQL sorgusundan gelen veriyi kontrol et ve dönüştür $sectionValue = null; if (is_object($detail)) { $sectionValue = isset($detail->section) ? $detail->section : null; } elseif (is_array($detail)) { $sectionValue = isset($detail['section']) ? $detail['section'] : null; } $section = intval($sectionValue); // logProcessInfo('Processing detail row section data', [ // 'raw_section' => $sectionValue, // 'converted_section' => $section, // 'detail_data' => json_encode($detail, JSON_PRETTY_PRINT) // ]); if (!in_array($section, [1, 2, 3])) { // logProcessInfo('Invalid section value', [ // 'section' => $section, // 'expected' => [1, 2, 3] // ], 'error'); continue; } if (!isset($sectionedDetails[$section])) { $sectionedDetails[$section] = []; } $sectionedDetails[$section][] = $detail; } // logProcessInfo('Grouped details by section', [ // 'sections_found' => array_keys($sectionedDetails), // 'counts_per_section' => array_map('count', $sectionedDetails) // ]); // Her bir tekrarlanan satır için işlem yap $totalAddedRows = 0; // Önceki section'larda eklenen toplam satır sayısı foreach($repeatedRowsArray as $rowIndex => $rowNumber) { $currentSection = $rowIndex + 1; $originalStartRow = intval($rowNumber); // Önceki section'larda eklenen satır sayısı kadar kaydır $startRow = $originalStartRow + $totalAddedRows; // logProcessInfo('Processing repeated row with offset', [ // 'row_index' => $rowIndex, // 'current_section' => $currentSection, // 'original_template_row' => $originalStartRow, // 'adjusted_template_row' => $startRow, // 'total_added_rows' => $totalAddedRows, // 'has_section_data' => isset($sectionedDetails[$currentSection]) // ]); // Template satırından hücre değerlerini al $templateRowCells = []; $templateFormulas = []; try { foreach ($sheet->getRowIterator($startRow)->current()->getCellIterator() as $cell) { $templateRowCells[] = $cell->getValue(); if ($cell->isFormula()) { $colIndex = $cell->getColumn(); $templateFormulas[$colIndex] = $cell->getValue(); } } } catch (\Exception $e) { // logProcessInfo('Error reading template row', [ // 'original_row' => $originalStartRow, // 'adjusted_row' => $startRow, // 'error' => $e->getMessage() // ], 'error'); continue; } // Birleştirilmiş hücreleri kaydet $mergedCells = []; foreach ($sheet->getMergeCells() as $mergeRange) { list($startCell, $endCell) = explode(':', $mergeRange); $startCoordinates = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::coordinateFromString($startCell); $startRowNum = intval($startCoordinates[1]); if ($startRowNum == $startRow) { $mergedCells[] = [ 'range' => $mergeRange, 'start' => $startCell, 'end' => $endCell ]; } } // Section verilerini işle $sectionDetails = isset($sectionedDetails[$currentSection]) ? $sectionedDetails[$currentSection] : []; $hasData = !empty($sectionDetails); $addedRowsInCurrentSection = 0; // Bu section'da eklenen satır sayısı // Her durumda en az bir satır ekle (veri varsa veya yoksa) $newRowIndex = $startRow; $sheet->insertNewRowBefore($newRowIndex + 1, 1); $newRow = $sheet->getRowIterator($newRowIndex + 1)->current(); $addedRowsInCurrentSection++; if ($hasData) { // Section verisi varsa normal işleme devam et foreach($sectionDetails as $index => $detail) { if ($index > 0) { // İlk satırdan sonraki satırlar için yeni satır ekle $newRowIndex++; $sheet->insertNewRowBefore($newRowIndex + 1, 1); $newRow = $sheet->getRowIterator($newRowIndex + 1)->current(); $addedRowsInCurrentSection++; } // Detail verilerini hazırla $detailData = (array)$detail; $detailData['row_index'] = $index + 1; // Yeni satıra değerleri yerleştir $cellIndex = 0; foreach ($newRow->getCellIterator() as $newCell) { $newCellValue = $templateRowCells[$cellIndex]; $colLetter = $newCell->getColumn(); if (isset($templateFormulas[$colLetter])) { $formula = $templateFormulas[$colLetter]; // Formüldeki tüm hücre referanslarını güncelle // (1) Standart referanslar: A1, B2, C3 vb. // (2) İşlem içindekiler: +A1, -B2, *C3 vb. // (3) Fonksiyon içindekiler: SUM(A1:A10), AVERAGE(B1:B10) vb. // (4) Türkçe formül içindekiler: BİRLEŞTİR(A1;" "), EĞER(A1>0;A2;A3) vb. // Satır bazlı formül güncelleme fonksiyonu $updateRowReferences = function($formula, $rowOffset) { // Tüm olası hücre referanslarını bul ve güncelle return preg_replace_callback( '/([A-Z]+)(\d+)/', function($matches) use ($rowOffset) { $col = $matches[1]; $row = intval($matches[2]); // Satır numarasını offset kadar artır $row += $rowOffset; return $col . $row; }, $formula ); }; // İndeks değerine göre satır numaralarını artıralım // Burada her yeni eklenen satır için formülleri güncelleyeceğiz $rowOffset = $index + 1; // İndekse göre satır numarasını artır // Formülü güncelle $updatedFormula = $updateRowReferences($formula, $rowOffset); // Formülü hücreye uygula $newCell->setValue($updatedFormula); } else { // Placeholder değişimlerini yap foreach($detailData as $field => $value) { $newCellValue = str_replace('{'.$field.'}', $value ?? '', $newCellValue); } // Kalan placeholder'ları temizle $newCellValue = preg_replace('/\{[^}]+\}/', '', $newCellValue); // Converter-map çevirisini uygula $newCellValue = converterMapStringReplacer($newCellValue); $newCell->setValue($newCellValue); } $cellIndex++; } // Birleştirilmiş hücreleri yeni satıra uygula foreach ($mergedCells as $mergeInfo) { $originalRange = $mergeInfo['range']; list($startCell, $endCell) = explode(':', $originalRange); $newStartCell = preg_replace('/\d+/', $newRowIndex + 1, $startCell); $newEndCell = preg_replace('/\d+/', $newRowIndex + 1, $endCell); $newRange = $newStartCell . ':' . $newEndCell; try { $sheet->mergeCells($newRange); } catch (\Exception $e) { // logProcessInfo('Merge cells error', [ // 'error' => $e->getMessage(), // 'range' => $newRange // ], 'error'); } } } } else { // Section verisi yoksa placeholder'ları temizle ve boş satır ekle $cellIndex = 0; foreach ($newRow->getCellIterator() as $newCell) { $newCellValue = $templateRowCells[$cellIndex]; // Tüm placeholder'ları temizle $newCellValue = preg_replace('/\{[^}]+\}/', '', $newCellValue); // Converter-map çevirisini uygula $newCellValue = converterMapStringReplacer($newCellValue); $newCell->setValue($newCellValue); $cellIndex++; } // Birleştirilmiş hücreleri yeni satıra uygula foreach ($mergedCells as $mergeInfo) { $originalRange = $mergeInfo['range']; list($startCell, $endCell) = explode(':', $originalRange); $newStartCell = preg_replace('/\d+/', $newRowIndex + 1, $startCell); $newEndCell = preg_replace('/\d+/', $newRowIndex + 1, $endCell); $newRange = $newStartCell . ':' . $newEndCell; try { $sheet->mergeCells($newRange); } catch (\Exception $e) { // logProcessInfo('Merge cells error', [ // 'error' => $e->getMessage(), // 'range' => $newRange // ], 'error'); } } } // Template satırını sil try { $sheet->removeRow($startRow); // logProcessInfo('Template row removed', [ // 'section' => $currentSection, // 'original_row' => $originalStartRow, // 'adjusted_row' => $startRow, // 'added_rows' => $addedRowsInCurrentSection, // 'had_data' => $hasData // ]); } catch (\Exception $e) { // logProcessInfo('Error removing template row', [ // 'section' => $currentSection, // 'row' => $startRow, // 'error' => $e->getMessage() // ], 'error'); } // Toplam eklenen satır sayısını güncelle $totalAddedRows += ($addedRowsInCurrentSection - 1); // Template satırı silindiği için 1 çıkar // logProcessInfo('Section processing completed', [ // 'section' => $currentSection, // 'added_rows_in_section' => $addedRowsInCurrentSection, // 'total_added_rows' => $totalAddedRows // ]); } } else { // Mevcut single repeated row işleme kodu $startRow = $templateRowNo; $templateRowCells = []; $templateFormulas = []; // Iterate through the template row and save cell values and merge information foreach ($sheet->getRowIterator($startRow)->current()->getCellIterator() as $cell) { $templateRowCells[] = $cell->getValue(); // Formül varsa orijinal formülü de kaydedelim if ($cell->isFormula()) { $colIndex = $cell->getColumn(); $templateFormulas[$colIndex] = $cell->getValue(); } } // Loop through all the cells in the sheet and replace placeholders foreach($resultDetail AS $index => $detailRowData) { // Save the template row's cell values and merge information $mergedCells = []; // Save merged cell ranges in the template row foreach ($sheet->getMergeCells() as $mergeRange) { // Check if the merge range starts in the template row if (preg_match('/^\D*'.$startRow.'$/', explode(':', $mergeRange)[0])) { $mergedCells[] = $mergeRange; } } // Insert a new row before the next one (clone the template row) $sheet->insertNewRowBefore($startRow + 1, 1); // Get the newly inserted row $newRow = $sheet->getRowIterator($startRow + 1)->current(); // Copy template row's values to the new row $cellIndex = 0; // To keep track of which cell we're on foreach ($newRow->getCellIterator() as $newCell) { // Set the template value to the new cell $newCellValue = $templateRowCells[$cellIndex]; $colLetter = $newCell->getColumn(); // Eğer bu hücrede bir formül varsa if (isset($templateFormulas[$colLetter])) { $formula = $templateFormulas[$colLetter]; // Formüldeki tüm hücre referanslarını güncelle // (1) Standart referanslar: A1, B2, C3 vb. // (2) İşlem içindekiler: +A1, -B2, *C3 vb. // (3) Fonksiyon içindekiler: SUM(A1:A10), AVERAGE(B1:B10) vb. // (4) Türkçe formül içindekiler: BİRLEŞTİR(A1;" "), EĞER(A1>0;A2;A3) vb. // Satır bazlı formül güncelleme fonksiyonu $updateRowReferences = function($formula, $rowOffset) { // Tüm olası hücre referanslarını bul ve güncelle return preg_replace_callback( '/([A-Z]+)(\d+)/', function($matches) use ($rowOffset) { $col = $matches[1]; $row = intval($matches[2]); // Satır numarasını offset kadar artır $row += $rowOffset; return $col . $row; }, $formula ); }; // İndeks değerine göre satır numaralarını artıralım // Burada her yeni eklenen satır için formülleri güncelleyeceğiz $rowOffset = $index + 1; // İndekse göre satır numarasını artır // Formülü güncelle $updatedFormula = $updateRowReferences($formula, $rowOffset); // Formülü hücreye uygula $newCell->setValue($updatedFormula); } else { // Formül değilse, normal placeholder değişimini yap // Detail için sıcaklık değerlerini hesapla $detailData = (array) $detailRowData; // logProcessInfo('index', [ // 'index' => $index, // ]); // Satır indeksi ekle - burada 1'den başlıyoruz çünkü kullanıcılar genelde 0'dan başlayan indeksleri değil 1'den başlayan satır numaralarını bekler $detailData['row_index'] = $index + 1; if (isset($detailData['welding_date']) && isset($detailData['type_of_joint'])) { $tempData = $temperatures[date("z", strtotime($detailData['welding_date']))]; if ($detailData['type_of_joint'] == "S") { $thisTempData = $tempData['shop_ambient']; $thisTempData2 = $tempData['temp_material_shop']; } else { $thisTempData = $tempData['field_ambient']; $thisTempData2 = $tempData['temp_material_field']; } // Sıcaklık placeholder'larını ekle $detailData['temp_data_ambient'] = "{$detailData['welding_date']} \n $thisTempData °С"; $detailData['temp_data_material'] = "{$detailData['welding_date']} \n $thisTempData2 °С"; } foreach($detailData AS $field => $value) { $newCellValue = str_replace('{'.$field.'}', $value, $newCellValue); } // Converter-map çevirisini uygula $newCellValue = converterMapStringReplacer($newCellValue); // Set the new value in the cell $newCell->setValue($newCellValue); } $cellIndex++; // Move to the next cell } // Apply merged cells to the new row foreach ($mergedCells as $mergeRange) { // Adjust the merge range to the new row $adjustedMergeRange = preg_replace_callback('/\d+/', function($matches) use ($startRow) { return $matches[0] + 1; // Shift row numbers by 1 for the newly inserted row }, $mergeRange); // Apply the adjusted merge range to the new row $sheet->mergeCells($adjustedMergeRange); } // Move to the next row for the next weld log entry $startRow++; } // After inserting all new rows, remove the original template row $sheet->removeRow(intval($templateRowNo)); } } $path = $documentInfo->kid; //"005_PTO/06_Прочность и плотность"; $fileName = str_replace("/", "-", $fileName); $path = "storage/documents/$path/$fileName.xlsx"; if (!file_exists(dirname($path))) { mkdir(dirname($path), 0777, true); // logProcessInfo('Created directory structure', [ // 'path' => dirname($path) // ]); } // Save the modified spreadsheet try { // Dosya yazılmadan önce debug çıktısı // echo "Excel dosyası yazılmaya başlanıyor. Bellek kullanımı: " . (memory_get_usage(true) / 1024 / 1024) . " MB\n"; // Daha hafif yazıcı seçeneği kullanabiliriz $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); // $writer->setPreCalculateFormulas(false); // Formülleri önceden hesaplama - performans artışı // Yazma işlemi $writer->save($path); // echo "Excel dosyası yazıldı. Bellek kullanımı: " . (memory_get_usage(true) / 1024 / 1024) . " MB\n"; } catch (\Exception $e) { // echo "Hata oluştu: " . $e->getMessage(); // dd($e); // Detaylı hata bilgisi } // Belleği temizle // logProcessInfo('Cleaning up spreadsheet memory', [ // 'master_index' => $masterIndex, // 'memory_before_cleanup' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); $spreadsheet->disconnectWorksheets(); unset($spreadsheet); gc_collect_cycles(); // logProcessInfo('Memory cleanup completed', [ // 'master_index' => $masterIndex, // 'memory_after_cleanup' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); $processingEnd = microtime(true); // logProcessInfo('Excel file saved successfully', [ // 'master_index' => $masterIndex, // 'file_path' => $path, // 'processing_time' => round($processingEnd - $processingStart, 2) . ' seconds', // 'memory_peak' => round(memory_get_peak_usage() / 1024 / 1024, 2) . ' MB' // ]); // Log::debug('🟦 [START] PDF Generation', ['master_index' => $masterIndex, 'timestamp' => now()->format('Y-m-d H:i:s')]); try { $pdfResult = xlsx_to_pdf($path, "storage/documents/{$documentInfo->kid}"); if ($pdfResult['success']) { // PDF başarıyla oluşturuldu // logProcessInfo('PDF generation completed', [ // 'master_index' => $masterIndex, // 'pdf_path' => $pdfResult['output_file'], // 'message' => $pdfResult['message'], // 'memory_after_pdf' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Log::debug('🟦 [END] PDF Generation', [ // 'master_index' => $masterIndex, // 'timestamp' => now()->format('Y-m-d H:i:s'), // 'pdf_file' => $pdfResult['output_file'] // ]); echo "✅ PDF başarıyla oluşturuldu: " . ($pdfResult['output_file']) . "\n"; // PDF dosya yolunu döndür (diğer işlemler için) $pdfPath = $pdfResult['output_file']; } else { // PDF oluşturulamadı // logProcessInfo('PDF generation failed', [ // 'master_index' => $masterIndex, // 'excel_path' => $path, // 'error' => $pdfResult['error'], // 'memory_after_pdf' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ], 'error'); // Log::debug('🟦 [ERROR] PDF Generation', [ // 'master_index' => $masterIndex, // 'timestamp' => now()->format('Y-m-d H:i:s'), // 'error' => $pdfResult['error'] // ]); echo "❌ PDF oluşturulamadı: " . $pdfResult['error'] . "\n"; // Hata durumunda null döndür $pdfPath = null; } } catch (\Exception $e) { // logProcessInfo('Error in PDF generation', [ // 'master_index' => $masterIndex, // 'excel_path' => $path, // 'error' => $e->getMessage() // ], 'error'); // Exception durumunda PDF path'i null yap $pdfPath = null; throw $e; } // PDF başarıyla oluşturulduysa ek işlemler yapılabilir if ($pdfPath !== null) { // PDF dosyası başarıyla oluşturuldu, gerekirse ek işlemler burada yapılabilir // Örneğin: veritabanına kaydetme, email gönderme, vb. // logProcessInfo('PDF post-processing started', [ // 'master_index' => $masterIndex, // 'pdf_path' => $pdfPath, // 'file_size' => file_exists($pdfPath) ? round(filesize($pdfPath) / 1024, 2) . ' KB' : 'N/A' // ]); } } catch (\Exception $e) { // logProcessInfo('Error in master row processing', [ // 'master_index' => $masterIndex, // 'processed_count' => $processedCount, // 'error' => $e->getMessage(), // 'trace' => $e->getTraceAsString() // ], 'error'); throw $e; } } // Batch sonunda bellek temizleme // logProcessInfo('Batch completed', [ // 'batch_index' => $batchIndex + 1, // 'processed_count' => $processedCount, // 'memory_after_batch' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); // Agresif bellek temizleme gc_collect_cycles(); // Bellek kullanımını kontrol et $memoryUsageMB = round(memory_get_usage() / 1024 / 1024, 2); $memoryLimitMB = 1500; // 1.5GB limit if ($memoryUsageMB > $memoryLimitMB) { // logProcessInfo('High memory usage detected, forcing cleanup', [ // 'batch_index' => $batchIndex + 1, // 'memory_usage' => $memoryUsageMB . ' MB', // 'memory_limit' => $memoryLimitMB . ' MB' // ], 'warning'); // Agresif temizleme if (function_exists('opcache_reset')) { opcache_reset(); } gc_collect_cycles(); // logProcessInfo('Forced memory cleanup completed', [ // 'memory_after_cleanup' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); } // Her 10 batch'te bir daha agresif temizleme if (($batchIndex + 1) % 10 == 0) { // logProcessInfo('Deep memory cleanup after 10 batches', [ // 'batch_index' => $batchIndex + 1, // 'memory_before_cleanup' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); if (function_exists('opcache_reset')) { opcache_reset(); } // logProcessInfo('Deep memory cleanup completed', [ // 'memory_after_cleanup' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB' // ]); } } $endTime = microtime(true); // Log::debug('🏁 [END] Complete process', [ // 'timestamp' => now()->format('Y-m-d H:i:s'), // 'total_time' => round($endTime - $startTime, 2) . ' seconds', // 'memory_peak' => round(memory_get_peak_usage() / 1024 / 1024, 2) . ' MB' // ]); logProcessInfo('Complete process finished', [ 'total_time' => round($endTime - $startTime, 2) . ' MB' ]); } catch (\Exception $e) { // logProcessInfo('Fatal error in PDF generation process', [ // 'error' => $e->getMessage(), // 'trace' => $e->getTraceAsString() // ], 'error'); throw $e; } ?>