feature/excel #1

Open
mmintel wants to merge 84 commits from feature/excel into main
43 changed files with 147 additions and 117 deletions
Showing only changes of commit dd27f77c71 - Show all commits

View File

@@ -104,46 +104,76 @@ function generateExcelForProduct(product: ProductData): Buffer {
const workbook = XLSX.utils.book_new();
const l = product.locale === 'de';
// Single sheet: all cross-sections from all voltage tables combined
const hasMultipleVoltages = product.voltageTables.length > 1;
const allRows: string[][] = [];
const allRows: any[][] = [];
// Build unified header row
// Use columns from the first voltage table (they're the same across tables)
const refTable = product.voltageTables[0];
if (!refTable) {
// No voltage tables — create a minimal info sheet
const ws = XLSX.utils.aoa_to_sheet([
[product.title],
[l ? 'Keine Querschnittsdaten verfügbar' : 'No cross-section data available'],
]);
ws['!cols'] = [{ wch: 40 }];
XLSX.utils.book_append_sheet(workbook, ws, product.title.substring(0, 31));
return Buffer.from(XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' }));
// --- 1. Product Meta Data ---
allRows.push([product.title]);
const categoriesLine = product.categories.join(' • ');
if (categoriesLine) {
allRows.push([l ? 'Kategorien:' : 'Categories:', categoriesLine]);
}
if (product.sku) {
allRows.push([l ? 'Artikelnummer:' : 'SKU:', product.sku]);
}
allRows.push([]); // blank row
// --- 2. Application / Description ---
if (product.description) {
allRows.push([l ? 'ANWENDUNG' : 'APPLICATION']);
allRows.push([product.description]);
allRows.push([]); // blank row
}
// --- 3. Technical Specifications ---
if (product.technicalItems && product.technicalItems.length > 0) {
allRows.push([l ? 'TECHNISCHE DATEN' : 'TECHNICAL DATA']);
for (const item of product.technicalItems) {
const val = item.unit ? `${item.value} ${item.unit}` : item.value;
allRows.push([item.label, val]);
}
allRows.push([]); // blank row
}
// --- 4. Cross-section Configurations ---
const hasMultipleVoltages = product.voltageTables.length > 1;
if (product.voltageTables.length > 0) {
allRows.push([l ? 'KONFIGURATIONEN' : 'CONFIGURATIONS']);
const refTable = product.voltageTables[0];
const headers: string[] = [
l ? 'Querschnitt' : 'Cross-section',
...(hasMultipleVoltages ? [l ? 'Spannung' : 'Voltage'] : []),
...refTable.columns.map(c => c.label),
...refTable.columns.map((c) => c.label),
];
allRows.push(headers);
// Merge rows from all voltage tables
for (const table of product.voltageTables) {
for (let rowIdx = 0; rowIdx < table.crossSections.length; rowIdx++) {
const row: string[] = [
table.crossSections[rowIdx],
...(hasMultipleVoltages ? [table.voltageLabel] : []),
...table.columns.map(c => c.get(rowIdx) || '-'),
...table.columns.map((c) => c.get(rowIdx) || '-'),
];
allRows.push(row);
}
}
} else {
allRows.push([l ? 'Keine Querschnittsdaten verfügbar' : 'No cross-section data available']);
}
const ws = XLSX.utils.aoa_to_sheet(allRows);
// Auto-width: first col wider for cross-section labels
ws['!cols'] = headers.map((_, i) => ({ wch: i === 0 ? 30 : 18 }));
// Auto-width: Col 0 wide for description, headers.
ws['!cols'] = [
{ wch: 45 },
{ wch: 20 },
{ wch: 15 },
{ wch: 15 },
{ wch: 15 },
{ wch: 15 },
{ wch: 15 },
{ wch: 15 },
];
const sheetName = product.title.substring(0, 31);
XLSX.utils.book_append_sheet(workbook, ws, sheetName);