Skip to content

Commit f3ef6d1

Browse files
committed
added service and other dropdown list to mapping sheet
1 parent 963432e commit f3ef6d1

File tree

1 file changed

+85
-68
lines changed

1 file changed

+85
-68
lines changed

src/index.js

Lines changed: 85 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -138,98 +138,115 @@ const uploadToAWS = async (config, excelData) => {
138138
}
139139

140140
async function injectFormulasIntoSheet(workbook, data, config) {
141-
const sheetName = config.dependentSheet
142-
const sheet = workbook.getWorksheet(sheetName) || workbook.worksheets[0]
143-
if (!sheet) throw new Error('Target sheet not found')
144141
const lookupSheet = config.lookupSheet
145142
const hiddenSheet = workbook.getWorksheet(lookupSheet) || workbook.addWorksheet(lookupSheet)
146143
hiddenSheet.state = 'veryHidden'
147-
const { primaryKey, dependentKeys = [], lookupKeys = [] } = config
148-
if (!primaryKey) throw new Error("Config must specify primaryKey")
149-
const allGroups = [primaryKey, ...lookupKeys, ...dependentKeys].map(k => Array.isArray(k) ? k : [k])
150-
const canonicalKeys = allGroups.map(g => g[0]) // always first alias = canonical key
151-
hiddenSheet.getRows(1, hiddenSheet.rowCount).forEach(r => {
152-
r.eachCell(c => { c.value = null })
153-
})
154-
hiddenSheet.getRow(1).values = canonicalKeys
155-
let currentRow = 2
156-
data.forEach((row) => {
157-
const baseRow = {}
158-
Object.keys(row).forEach(k => {
159-
baseRow[k.toLowerCase()] = row[k]
160-
})
161-
const maxArrayLength = Math.max(
162-
...canonicalKeys.map(key => Array.isArray(baseRow[key]) ? baseRow[key].length : 1)
163-
)
164-
for (let i = 0; i < maxArrayLength; i++) {
165-
const rowValues = canonicalKeys.map(key => {
166-
const val = baseRow[key]
167-
if (Array.isArray(val)) {
168-
return val[i] || ""
169-
} else {
170-
return i === 0 ? val || "" : ""
171-
}
172-
})
173-
hiddenSheet.getRow(currentRow).values = rowValues
174-
currentRow++
175-
}
176-
})
177-
const lastRow = currentRow -1
178-
const primaryRange = `Lookups!$A$2:$A$${lastRow}`
179144

180-
const findCol = (aliases) => {
145+
const headerKeys = [
146+
...new Set(
147+
data.flatMap(row => Object.keys(row))
148+
)
149+
];
150+
151+
// Column-wise data insertion into hidden sheet
152+
headerKeys.forEach((key, idx) => {
153+
const values = data.flatMap(row => row[key] ?? []);
154+
values.forEach((val, rowIndex) => {
155+
hiddenSheet.getRow(rowIndex + 2).getCell(idx + 1).value = val ?? "";
156+
});
157+
hiddenSheet.getRow(1).getCell(idx + 1).value = key;
158+
});
159+
const findCol = (sheet, aliases) => {
181160
const headerRow = sheet.getRow(1)
182161
const lookupNames = Array.isArray(aliases) ? aliases : [aliases]
183162

184163
for (let col = 1; col <= sheet.columnCount; col++) {
185164
const val = headerRow.getCell(col)?.value
186-
const text = typeof val === 'object'
187-
? (val?.richText?.map(rt => rt.text).join('') || val?.result || '')
188-
: (val || '')
189-
const normalized = String(text).trim().toLowerCase()
165+
let text = '';
166+
167+
if (typeof val === 'object') {
168+
if (Array.isArray(val.richText)) {
169+
text = val.richText.map(rt => rt.text).join('');
170+
} else if (val.result) {
171+
text = val.result;
172+
}
173+
} else if (val !== null && val !== undefined) {
174+
text = val;
175+
}
176+
177+
const normalized = String(text || '').trim().toLowerCase();
190178

191179
for (const alias of lookupNames) {
192-
const normAlias = alias.trim().toLowerCase()
180+
if (!alias) continue;
181+
const normAlias = String(alias).trim().toLowerCase()
193182
if (normalized === normAlias) return col
194-
if (normalized.replace(/\s+/g, "_") === normAlias) return col // "Country Code" -> country_code
195-
if (normalized.replace(/[^a-z0-9]/gi, "") === normAlias.replace(/[^a-z0-9]/gi, "")) return col // remove *, etc.
183+
if (normalized.replace(/\s+/g, "_") === normAlias) return col
184+
if (normalized.replace(/[^a-z0-9]/gi, "") === normAlias.replace(/[^a-z0-9]/gi, "")) return col
196185
}
197186
}
198187
return null
199188
}
200-
// --- Primary key col ---
201-
const colPrimary = findCol(primaryKey)
202-
if (!colPrimary) throw new Error(`Primary key column ${primaryKey} not found in sheet`)
189+
for (const sheetConfig of config.dependentSheet) {
190+
const sheet = workbook.getWorksheet(sheetConfig.name);
191+
if (!sheet) throw new Error(`Sheet ${sheetConfig.name} not found`);
192+
193+
const lastRow = hiddenSheet.lastRow.number;
194+
195+
//Primary key dropdown (if exists)
196+
let primaryCol = null;
197+
let primaryCell = null;
203198

204-
const row = 2
205-
const primaryCell = sheet.getRow(row).getCell(colPrimary)
199+
if (sheetConfig.primaryKey) {
200+
primaryCol = findCol(sheet, sheetConfig.primaryKey);
201+
if (!primaryCol) throw new Error(`Primary key not found in ${sheetConfig.name}`);
202+
primaryCell = sheet.getRow(2).getCell(primaryCol);
203+
204+
const lookupCol = findCol(hiddenSheet, sheetConfig.primaryKey);
205+
if (!lookupCol) throw new Error(`Primary key not found in Lookups sheet`);
206+
const lookupColLetter = String.fromCharCode(64 + lookupCol);
207+
208+
primaryCell.dataValidation = {
209+
type: "list",
210+
allowBlank: true,
211+
formulae: [`${hiddenSheet.name}!$${lookupColLetter}$2:$${lookupColLetter}$${lastRow}`],
212+
};
213+
}
206214
//Dependent dropdowns
207-
for (const depGroup of dependentKeys) {
208-
const colDep = findCol(depGroup)
209-
if (!colDep) continue
210-
const depKey = Array.isArray(depGroup) ? depGroup[0] : depGroup
211-
const depCell = sheet.getRow(row).getCell(colDep)
212-
const depColLetter = String.fromCharCode(65 + canonicalKeys.indexOf(depKey))
215+
for (const depGroup of sheetConfig.dependentKeys || []) {
216+
const depCol = findCol(sheet, depGroup);
217+
if (!depCol) continue;
218+
219+
const depCell = sheet.getRow(2).getCell(depCol);
220+
221+
const lookupCol = findCol(hiddenSheet, depGroup);
222+
if (!lookupCol) continue;
223+
const lookupColLetter = String.fromCharCode(64 + lookupCol);
224+
213225
depCell.dataValidation = {
214-
type: 'list',
226+
type: "list",
215227
allowBlank: true,
216-
formulae: [`Lookups!$${depColLetter}$2:$${depColLetter}$${lastRow}`],
217-
}
228+
formulae: [`${hiddenSheet.name}!$${lookupColLetter}$2:$${lookupColLetter}$${lastRow}`],
229+
};
218230
}
219-
//Lookup autofill
220-
for (const lookupGroup of lookupKeys) {
221-
const colLookup = findCol(lookupGroup)
222-
if (!colLookup) continue
223-
const lookupKey = Array.isArray(lookupGroup) ? lookupGroup[0] : lookupGroup
224-
const lookupCell = sheet.getRow(row).getCell(colLookup)
225-
const lookupColIndex = canonicalKeys.indexOf(lookupKey) + 1
226-
lookupCell.value = {
227-
formula: `IF(${primaryCell.address}="","",VLOOKUP(${primaryCell.address},Lookups!$A$2:$${String.fromCharCode(64 + canonicalKeys.length)}$${lastRow},${lookupColIndex},FALSE))`
231+
232+
//Lookup autofill (only if primary key exists)
233+
if (primaryCol && sheetConfig.lookupKeys) {
234+
for (const lookupGroup of sheetConfig.lookupKeys) {
235+
const lookupCol = findCol(sheet, lookupGroup);
236+
if (!lookupCol) continue;
237+
const lookupKey = Array.isArray(lookupGroup) ? lookupGroup[0] : lookupGroup;
238+
const lookupColIndex = headerKeys.indexOf(lookupKey) + 1;
239+
const lookupCell = sheet.getRow(2).getCell(lookupCol);
240+
241+
lookupCell.value = {
242+
formula: `IF(${primaryCell.address}="","",VLOOKUP(${primaryCell.address},${hiddenSheet.name}!$A$2:$${String.fromCharCode(
243+
64 + headerKeys.length
244+
)}$${lastRow},${lookupColIndex},FALSE))`,
245+
};
228246
}
229247
}
230-
231248
}
232-
249+
}
233250

234251
const convertJsonToExcel = (jsonData) => {
235252
const workbook = xlsx.utils.book_new()

0 commit comments

Comments
 (0)