diff --git a/public/userarea/mapping_template_xls_scheme2.php b/public/userarea/mapping_template_xls_scheme2.php
index b7ddbc7..6523bce 100644
--- a/public/userarea/mapping_template_xls_scheme2.php
+++ b/public/userarea/mapping_template_xls_scheme2.php
@@ -198,7 +198,13 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
-
+
+
+
+
✅ Current file:
@@ -508,8 +514,6 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
type: 'array'
});
let sheet = workbook.Sheets[workbook.SheetNames[0]];
- let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1;
- let startColumn = parseInt(document.getElementById('startColumn').textContent) || 1;
let sheetData = XLSX.utils.sheet_to_json(sheet, {
header: 1,
@@ -517,37 +521,152 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
raw: false,
range: 0
});
- console.log("Dati della riga " + rowIndex + ":", sheetData[rowIndex - 1]);
- if (!sheetData[rowIndex - 1]) {
+
+ const useAutoDetect = document.getElementById('autoDetectHeader').checked;
+
+ if (!useAutoDetect) {
+ // Use values from template settings
+ let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1;
+ let startColumn = parseInt(document.getElementById('startColumn').textContent) || 1;
+ console.log(`Manual mode: row ${rowIndex}, startCol ${startColumn}`);
+
+ if (!sheetData[rowIndex - 1]) {
+ document.getElementById('schemaFieldsBody').querySelectorAll('select.xls-columns').forEach(select => {
+ select.innerHTML = '';
+ });
+ return;
+ }
+
+ let headers = sheetData[rowIndex - 1].slice(startColumn - 1).map(header => header === undefined ? "" : String(header).trim());
+ console.log("Intestazioni estratte (manual):", headers);
+ availableXlsColumns = [...headers];
+ usedColumnsFromDB = [];
+ saveXlsHeaders(headers, rowIndex, startColumn);
+ updateXlsDropdowns();
+ return;
+ }
+
+ // Collect field_label titles from the schema table
+ const knownLabels = [];
+ document.querySelectorAll('.title-col').forEach(td => {
+ const v = (td.textContent || '').trim().toLowerCase().replace(/\s*required\s*$/i, '').trim();
+ if (v && v !== 'n/a') knownLabels.push(v);
+ });
+ const uniqueLabels = [...new Set(knownLabels)];
+
+ console.group('🔍 Auto-detect header row');
+ console.log('Sheet name:', workbook.SheetNames[0]);
+ console.log('Total rows in sheet:', sheetData.length);
+ console.log('Labels from schema field titles:', knownLabels);
+ console.log('Unique labels to match against:', uniqueLabels);
+
+ // Auto-detect: find the row with most matches, fallback to most non-empty unique text cells
+ let bestRow = 0;
+ let bestScore = 0;
+ let bestStartCol = 0;
+ let fallbackRow = 0;
+ let fallbackScore = 0;
+ let fallbackStartCol = 0;
+ const scanLimit = Math.min(sheetData.length, 50);
+ const rowScores = [];
+
+ for (let r = 0; r < scanLimit; r++) {
+ const row = sheetData[r] || [];
+ let score = 0;
+ let firstNonEmpty = -1;
+ let nonEmptyCount = 0;
+ const matched = [];
+ const cellValues = [];
+ const seen = new Set();
+ for (let c = 0; c < row.length; c++) {
+ const cellVal = String(row[c] || '').trim();
+ const cellLower = cellVal.toLowerCase();
+ if (cellVal) {
+ cellValues.push(`[${c}]="${cellVal}"`);
+ if (firstNonEmpty < 0) firstNonEmpty = c;
+ // Count unique short text cells (likely headers, not data/descriptions)
+ if (cellVal.length < 80 && !seen.has(cellLower)) {
+ nonEmptyCount++;
+ seen.add(cellLower);
+ }
+ }
+ if (cellLower && uniqueLabels.includes(cellLower)) {
+ score++;
+ matched.push(cellVal);
+ }
+ }
+ rowScores.push({ row: r + 1, score, nonEmpty: nonEmptyCount, matched, firstNonEmpty: firstNonEmpty + 1, cells: cellValues });
+ if (score > bestScore) {
+ bestScore = score;
+ bestRow = r;
+ bestStartCol = firstNonEmpty >= 0 ? firstNonEmpty : 0;
+ }
+ // Fallback: row with most unique short text cells (likely header row)
+ if (nonEmptyCount > fallbackScore) {
+ fallbackScore = nonEmptyCount;
+ fallbackRow = r;
+ fallbackStartCol = firstNonEmpty >= 0 ? firstNonEmpty : 0;
+ }
+ }
+
+ // If no label matches, use fallback (most populated row)
+ if (bestScore === 0 && fallbackScore > 0) {
+ bestRow = fallbackRow;
+ bestStartCol = fallbackStartCol;
+ console.log(`⚠️ No label matches found. Using fallback: row with most headers (${fallbackScore} unique cells)`);
+ }
+
+ console.log('All rows scanned:');
+ console.table(rowScores.filter(r => r.nonEmpty > 0).map(r => ({
+ row: r.row,
+ labelMatches: r.score,
+ uniqueCells: r.nonEmpty,
+ matched: r.matched.join(', '),
+ firstCol: r.firstNonEmpty
+ })));
+ console.log(`✅ Result: row ${bestRow + 1}, startCol ${bestStartCol + 1}, labelScore ${bestScore}/${uniqueLabels.length}, fallbackScore ${fallbackScore}`);
+ console.log('Selected row raw data:', sheetData[bestRow]);
+ console.groupEnd();
+
+ // Update display
+ document.getElementById('headerRow').textContent = bestRow + 1;
+ document.getElementById('startColumn').textContent = bestStartCol + 1;
+
+ if (!sheetData[bestRow]) {
document.getElementById('schemaFieldsBody').querySelectorAll('select.xls-columns').forEach(select => {
select.innerHTML = '';
});
return;
}
- let headers = sheetData[rowIndex - 1].slice(startColumn - 1).map(header => header === undefined ? "" : header);
+ let headers = sheetData[bestRow].slice(bestStartCol).map(header => header === undefined ? "" : String(header).trim());
console.log("Intestazioni estratte:", headers);
availableXlsColumns = [...headers];
usedColumnsFromDB = [];
- saveXlsHeaders(headers);
+ saveXlsHeaders(headers, bestRow + 1, bestStartCol + 1);
updateXlsDropdowns();
};
reader.readAsArrayBuffer(file);
}
- function saveXlsHeaders(headers) {
+ function saveXlsHeaders(headers, headerRow, startColumn) {
+ const payload = {
+ template_id: ,
+ xls_headers: JSON.stringify(headers)
+ };
+ if (headerRow !== undefined) payload.header_row = headerRow;
+ if (startColumn !== undefined) payload.start_column = startColumn;
+
fetch('update_xls_headers.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
- body: JSON.stringify({
- template_id: ,
- xls_headers: JSON.stringify(headers)
- })
+ body: JSON.stringify(payload)
}).then(response => response.json())
.then(data => {
if (!data.success) console.error("❌ Error saving XLS headers:", data.message);
+ else console.log("✅ Saved headers, header_row:", headerRow, "start_column:", startColumn);
})
.catch(error => console.error("❌ Fetch error:", error));
}
@@ -1582,4 +1701,4 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t