From aa1c32b7ed05694a6f73a2354e3efe2f54adafdf Mon Sep 17 00:00:00 2001 From: "r.mubarakzyanov" Date: Sun, 29 Mar 2026 21:07:16 +0300 Subject: [PATCH] autodetect mapping --- public/userarea/import_xls2.php | 2 +- public/userarea/process_import_xls2.php | 59 ++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/public/userarea/import_xls2.php b/public/userarea/import_xls2.php index 8c3d6af..0af5697 100644 --- a/public/userarea/import_xls2.php +++ b/public/userarea/import_xls2.php @@ -491,4 +491,4 @@ error_log("Loaded template: " . print_r($template, true)); - \ No newline at end of file + diff --git a/public/userarea/process_import_xls2.php b/public/userarea/process_import_xls2.php index 8f90fe4..4f29d15 100644 --- a/public/userarea/process_import_xls2.php +++ b/public/userarea/process_import_xls2.php @@ -58,6 +58,11 @@ try { $stmt->execute([$template_id]); $mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); + // Also fetch excel_column labels for auto-detect + $stmtLabels = $pdo->prepare("SELECT excel_column FROM template_mapping WHERE template_id = ? AND is_manual = 0 AND excel_column IS NOT NULL AND excel_column != ''"); + $stmtLabels->execute([$template_id]); + $templateLabels = array_map('trim', array_map('mb_strtolower', $stmtLabels->fetchAll(PDO::FETCH_COLUMN))); + // Debug dei mapping error_log("Mappings found for template_id $template_id: " . print_r($mappings, true)); @@ -71,6 +76,41 @@ try { $highestColumn = $worksheet->getHighestColumn(); $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); + // ── Auto-detect header row and start column ── + // Scan all rows/columns to find the best match against template excel_column labels + if (!empty($templateLabels)) { + $bestRow = max(1, $header_row); + $bestCol = max(1, $start_column); + $bestScore = 0; + $scanLimit = min($highestRow, 50); + + for ($scanRow = 1; $scanRow <= $scanLimit; $scanRow++) { + $score = 0; + $firstMatchCol = $highestColumnIndex + 1; + for ($col = 1; $col <= $highestColumnIndex; $col++) { + $colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); + $cellVal = $worksheet->getCell($colLetter . $scanRow)->getCalculatedValue(); + $cellVal = mb_strtolower(trim((string)$cellVal)); + if ($cellVal !== '' && in_array($cellVal, $templateLabels, true)) { + $score++; + if ($col < $firstMatchCol) $firstMatchCol = $col; + } + } + if ($score > $bestScore) { + $bestScore = $score; + $bestRow = $scanRow; + $bestCol = $firstMatchCol; + } + } + + $header_row = $bestRow; + $start_column = $bestCol; + error_log("Auto-detected header row: $header_row, start column: $start_column (score: $bestScore/" . count($templateLabels) . ")"); + $response['auto_header_row'] = $header_row; + $response['auto_header_score'] = $bestScore; + $response['auto_header_total'] = count($templateLabels); + } + $startRow = max(1, $header_row); $startColumn = max(1, $start_column); @@ -93,6 +133,14 @@ try { $headerRowData[] = $cellValue ?: ''; } + // Find which header columns are non-empty (these are the "real" columns) + $headerFilledIndices = []; + foreach ($headerRowData as $idx => $hVal) { + if (trim((string)$hVal) !== '') $headerFilledIndices[] = $idx; + } + // Require at least 2 filled header-columns (or 1 if only 1 exists) + $minFilled = max(1, min(2, count($headerFilledIndices))); + // Estrai i dati a partire dalla riga successiva, includendo excelrow for ($row = $startRow + 1; $row <= $highestRow; $row++) { $rowData = []; @@ -102,7 +150,16 @@ try { $cellValue = $cell ? $cell->getCalculatedValue() : ''; $rowData[] = $cellValue ?: ''; } - if (!empty(array_filter($rowData))) { + + // Count how many "header columns" have data in this row + $filledCount = 0; + foreach ($headerFilledIndices as $idx) { + if (isset($rowData[$idx]) && trim((string)$rowData[$idx]) !== '') { + $filledCount++; + } + } + + if ($filledCount >= $minFilled) { $excelData[] = ['data' => $rowData, 'excelrow' => $row]; } }