pdfs
This commit is contained in:
@@ -166,8 +166,22 @@ function findExcelRowsForProduct(product: ProductData): ExcelRow[] {
|
||||
|
||||
function guessColumnKey(row: ExcelRow, patterns: RegExp[]): string | null {
|
||||
const keys = Object.keys(row || {});
|
||||
|
||||
// Try pattern-based matching first
|
||||
for (const re of patterns) {
|
||||
const k = keys.find(x => re.test(String(x)));
|
||||
const k = keys.find(x => {
|
||||
const key = String(x);
|
||||
|
||||
// Specific exclusions to prevent wrong matches
|
||||
if (re.test('conductor') && /ross section conductor/i.test(key)) return false;
|
||||
if (re.test('insulation thickness') && /Diameter over insulation/i.test(key)) return false;
|
||||
if (re.test('conductor') && !/^conductor$/i.test(key)) return false;
|
||||
if (re.test('insulation') && !/^insulation$/i.test(key)) return false;
|
||||
if (re.test('sheath') && !/^sheath$/i.test(key)) return false;
|
||||
if (re.test('norm') && !/^norm$/i.test(key)) return false;
|
||||
|
||||
return re.test(key);
|
||||
});
|
||||
if (k) return k;
|
||||
}
|
||||
return null;
|
||||
@@ -240,15 +254,14 @@ function ensureExcelCrossSectionAttributes(product: ProductData, locale: 'en' |
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all technical column keys using improved detection
|
||||
const voltageKey = guessColumnKey(rows[0], [/rated voltage/i, /voltage rating/i, /spannungs/i, /nennspannung/i]);
|
||||
const outerKey = guessColumnKey(rows[0], [/outer diameter\b/i, /outer diameter.*approx/i, /outer diameter of cable/i, /außen/i]);
|
||||
const weightKey = guessColumnKey(rows[0], [/weight\b/i, /gewicht/i, /cable weight/i]);
|
||||
const dcResKey = guessColumnKey(rows[0], [/dc resistance/i, /resistance conductor/i, /leiterwiderstand/i]);
|
||||
|
||||
// Additional technical columns that are often missing from WP exports.
|
||||
// We add them as either constant attributes (if identical across all rows)
|
||||
// or as small multi-value arrays (if they vary), so TECHNICAL DATA can render them.
|
||||
const ratedVoltKey = guessColumnKey(rows[0], [/rated voltage/i, /voltage rating/i, /spannungs/i, /nennspannung/i]);
|
||||
|
||||
// Additional technical columns
|
||||
const ratedVoltKey = voltageKey; // Already found above
|
||||
const testVoltKey = guessColumnKey(rows[0], [/test voltage/i, /prüfspannung/i]);
|
||||
const tempRangeKey = guessColumnKey(rows[0], [/operating temperature range/i, /temperature range/i, /temperaturbereich/i]);
|
||||
const minLayKey = guessColumnKey(rows[0], [/minimal temperature for laying/i]);
|
||||
@@ -258,7 +271,35 @@ function ensureExcelCrossSectionAttributes(product: ProductData, locale: 'en' |
|
||||
const insThkKey = guessColumnKey(rows[0], [/nominal insulation thickness/i, /insulation thickness/i]);
|
||||
const sheathThkKey = guessColumnKey(rows[0], [/nominal sheath thickness/i, /minimum sheath thickness/i]);
|
||||
const maxResKey = guessColumnKey(rows[0], [/maximum resistance of conductor/i]);
|
||||
|
||||
|
||||
// Material and specification columns
|
||||
const conductorKey = guessColumnKey(rows[0], [/^conductor$/i]);
|
||||
const insulationKey = guessColumnKey(rows[0], [/^insulation$/i]);
|
||||
const sheathKey = guessColumnKey(rows[0], [/^sheath$/i]);
|
||||
const normKey = guessColumnKey(rows[0], [/^norm$/i, /^standard$/i]);
|
||||
const cprKey = guessColumnKey(rows[0], [/cpr class/i]);
|
||||
const rohsKey = guessColumnKey(rows[0], [/^rohs$/i]);
|
||||
const reachKey = guessColumnKey(rows[0], [/^reach$/i]);
|
||||
const packagingKey = guessColumnKey(rows[0], [/^packaging$/i]);
|
||||
const shapeKey = guessColumnKey(rows[0], [/shape of conductor/i]);
|
||||
const flameKey = guessColumnKey(rows[0], [/flame retardant/i]);
|
||||
const diamCondKey = guessColumnKey(rows[0], [/diameter conductor/i]);
|
||||
const diamInsKey = guessColumnKey(rows[0], [/diameter over insulation/i]);
|
||||
const diamScreenKey = guessColumnKey(rows[0], [/diameter over screen/i]);
|
||||
const metalScreenKey = guessColumnKey(rows[0], [/metallic screen/i]);
|
||||
const capacitanceKey = guessColumnKey(rows[0], [/capacitance/i]);
|
||||
const reactanceKey = guessColumnKey(rows[0], [/reactance/i]);
|
||||
const electricalStressKey = guessColumnKey(rows[0], [/electrical stress/i]);
|
||||
const pullingForceKey = guessColumnKey(rows[0], [/max\. pulling force/i, /pulling force/i]);
|
||||
const heatingTrefoilKey = guessColumnKey(rows[0], [/heating time constant.*trefoil/i]);
|
||||
const heatingFlatKey = guessColumnKey(rows[0], [/heating time constant.*flat/i]);
|
||||
const currentAirTrefoilKey = guessColumnKey(rows[0], [/current ratings in air.*trefoil/i]);
|
||||
const currentAirFlatKey = guessColumnKey(rows[0], [/current ratings in air.*flat/i]);
|
||||
const currentGroundTrefoilKey = guessColumnKey(rows[0], [/current ratings in ground.*trefoil/i]);
|
||||
const currentGroundFlatKey = guessColumnKey(rows[0], [/current ratings in ground.*flat/i]);
|
||||
const scCurrentCondKey = guessColumnKey(rows[0], [/conductor shortcircuit current/i]);
|
||||
const scCurrentScreenKey = guessColumnKey(rows[0], [/screen shortcircuit current/i]);
|
||||
|
||||
const cfgName = locale === 'de' ? 'Anzahl der Adern und Querschnitt' : 'Number of cores and cross-section';
|
||||
const cfgOptions = rows
|
||||
.map(r => {
|
||||
@@ -359,6 +400,139 @@ function ensureExcelCrossSectionAttributes(product: ProductData, locale: 'en' |
|
||||
key: maxResKey,
|
||||
});
|
||||
|
||||
// Add additional technical data from Excel files
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Leiter' : 'Conductor',
|
||||
existsRe: /conductor/i,
|
||||
key: conductorKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Isolierung' : 'Insulation',
|
||||
existsRe: /insulation/i,
|
||||
key: insulationKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Mantel' : 'Sheath',
|
||||
existsRe: /sheath/i,
|
||||
key: sheathKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Norm' : 'Standard',
|
||||
existsRe: /norm|standard|iec|vde/i,
|
||||
key: normKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Leiterdurchmesser' : 'Conductor diameter',
|
||||
existsRe: /diameter conductor|conductor diameter/i,
|
||||
key: diamCondKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Isolierungsdurchmesser' : 'Insulation diameter',
|
||||
existsRe: /diameter over insulation|diameter insulation/i,
|
||||
key: diamInsKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Schirmdurchmesser' : 'Screen diameter',
|
||||
existsRe: /diameter over screen|diameter screen/i,
|
||||
key: diamScreenKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Metallischer Schirm' : 'Metallic screen',
|
||||
existsRe: /metallic screen/i,
|
||||
key: metalScreenKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Max. Zugkraft' : 'Max. pulling force',
|
||||
existsRe: /max.*pulling force|pulling force/i,
|
||||
key: pullingForceKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Elektrische Spannung Leiter' : 'Electrical stress conductor',
|
||||
existsRe: /electrical stress conductor/i,
|
||||
key: electricalStressKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Elektrische Spannung Isolierung' : 'Electrical stress insulation',
|
||||
existsRe: /electrical stress insulation/i,
|
||||
key: electricalStressKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Reaktanz' : 'Reactance',
|
||||
existsRe: /reactance/i,
|
||||
key: reactanceKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Heizzeitkonstante trefoil' : 'Heating time constant trefoil',
|
||||
existsRe: /heating time constant.*trefoil/i,
|
||||
key: heatingTrefoilKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Heizzeitkonstante flach' : 'Heating time constant flat',
|
||||
existsRe: /heating time constant.*flat/i,
|
||||
key: heatingFlatKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Flammhemmend' : 'Flame retardant',
|
||||
existsRe: /flame retardant/i,
|
||||
key: flameKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'CPR-Klasse' : 'CPR class',
|
||||
existsRe: /cpr class/i,
|
||||
key: cprKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Verpackung' : 'Packaging',
|
||||
existsRe: /packaging/i,
|
||||
key: packagingKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Biegeradius' : 'Bending radius',
|
||||
existsRe: /bending radius/i,
|
||||
key: null, // Will be found in row-specific attributes
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Leiterform' : 'Shape of conductor',
|
||||
existsRe: /shape of conductor/i,
|
||||
key: shapeKey,
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Isolierungsfarbe' : 'Colour of insulation',
|
||||
existsRe: /colour of insulation/i,
|
||||
key: null, // Will be found in row-specific attributes
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'Mantelfarbe' : 'Colour of sheath',
|
||||
existsRe: /colour of sheath/i,
|
||||
key: null, // Will be found in row-specific attributes
|
||||
});
|
||||
|
||||
addConstOrSmallList({
|
||||
name: locale === 'de' ? 'RoHS/REACH' : 'RoHS/REACH',
|
||||
existsRe: /rohs.*reach/i,
|
||||
key: null, // Will be found in row-specific attributes
|
||||
});
|
||||
|
||||
product.attributes = attrs;
|
||||
|
||||
if (process.env.PDF_DEBUG_EXCEL === '1') {
|
||||
@@ -395,6 +569,21 @@ function ensureExcelRowSpecificAttributes(product: ProductData, locale: 'en' | '
|
||||
const keyScCond = guessColumnKey(sample, [/conductor shortcircuit current/i]);
|
||||
const keyScScreen = guessColumnKey(sample, [/screen shortcircuit current/i]);
|
||||
const keyBend = guessColumnKey(sample, [/bending radius/i, /min\. bending radius/i]);
|
||||
|
||||
// Additional row-specific technical data
|
||||
const keyConductorDiameter = guessColumnKey(sample, [/conductor diameter/i, /diameter conductor/i]);
|
||||
const keyInsulationThickness = guessColumnKey(sample, [/nominal insulation thickness/i, /insulation thickness/i]);
|
||||
const keySheathThickness = guessColumnKey(sample, [/nominal sheath thickness/i, /minimum sheath thickness/i, /sheath thickness/i]);
|
||||
const keyCapacitance = guessColumnKey(sample, [/capacitance/i]);
|
||||
const keyInductanceTrefoil = guessColumnKey(sample, [/inductance.*trefoil/i]);
|
||||
const keyInductanceAirFlat = guessColumnKey(sample, [/inductance.*air.*flat/i]);
|
||||
const keyInductanceGroundFlat = guessColumnKey(sample, [/inductance.*ground.*flat/i]);
|
||||
const keyCurrentAirTrefoil = guessColumnKey(sample, [/current.*air.*trefoil/i]);
|
||||
const keyCurrentAirFlat = guessColumnKey(sample, [/current.*air.*flat/i]);
|
||||
const keyCurrentGroundTrefoil = guessColumnKey(sample, [/current.*ground.*trefoil/i]);
|
||||
const keyCurrentGroundFlat = guessColumnKey(sample, [/current.*ground.*flat/i]);
|
||||
const keyHeatingTimeTrefoil = guessColumnKey(sample, [/heating.*time.*trefoil/i]);
|
||||
const keyHeatingTimeFlat = guessColumnKey(sample, [/heating.*time.*flat/i]);
|
||||
|
||||
const get = (k: string | null) => rows.map(r => normalizeValue(String(r?.[k ?? ''] ?? '')));
|
||||
const withUnit = (vals: string[], unit: string) => vals.map(v => (v && looksNumeric(v) ? `${v} ${unit}` : v));
|
||||
@@ -511,6 +700,111 @@ function ensureExcelRowSpecificAttributes(product: ProductData, locale: 'en' | '
|
||||
expectedLen: rowCount,
|
||||
existsRe: /bending\s*radius|biegeradius/i,
|
||||
});
|
||||
|
||||
// Additional row-specific technical data
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Leiterdurchmesser' : 'Conductor diameter',
|
||||
options: withUnit(get(keyConductorDiameter), 'mm'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /conductor diameter|diameter conductor/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Isolationsdicke' : 'Insulation thickness',
|
||||
options: withUnit(get(keyInsulationThickness), 'mm'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /insulation thickness|nominal insulation thickness/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Manteldicke' : 'Sheath thickness',
|
||||
options: withUnit(get(keySheathThickness), 'mm'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /sheath thickness|nominal sheath thickness/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Kapazität' : 'Capacitance',
|
||||
options: withUnit(get(keyCapacitance), 'μF/km'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /capacitance/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Induktivität trefoil' : 'Inductance trefoil',
|
||||
options: withUnit(get(keyInductanceTrefoil), 'mH/km'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /inductance.*trefoil/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Induktivität Luft flach' : 'Inductance air flat',
|
||||
options: withUnit(get(keyInductanceAirFlat), 'mH/km'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /inductance.*air.*flat/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Induktivität Erdreich flach' : 'Inductance ground flat',
|
||||
options: withUnit(get(keyInductanceGroundFlat), 'mH/km'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /inductance.*ground.*flat/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Strombelastbarkeit Luft trefoil' : 'Current rating air trefoil',
|
||||
options: withUnit(get(keyCurrentAirTrefoil), 'A'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /current.*air.*trefoil/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Strombelastbarkeit Luft flach' : 'Current rating air flat',
|
||||
options: withUnit(get(keyCurrentAirFlat), 'A'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /current.*air.*flat/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Strombelastbarkeit Erdreich trefoil' : 'Current rating ground trefoil',
|
||||
options: withUnit(get(keyCurrentGroundTrefoil), 'A'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /current.*ground.*trefoil/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Strombelastbarkeit Erdreich flach' : 'Current rating ground flat',
|
||||
options: withUnit(get(keyCurrentGroundFlat), 'A'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /current.*ground.*flat/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Heizzeitkonstante trefoil' : 'Heating time constant trefoil',
|
||||
options: withUnit(get(keyHeatingTimeTrefoil), 's'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /heating.*time.*trefoil/i,
|
||||
});
|
||||
|
||||
pushRowAttrIfMissing({
|
||||
product,
|
||||
name: locale === 'de' ? 'Heizzeitkonstante flach' : 'Heating time constant flat',
|
||||
options: withUnit(get(keyHeatingTimeFlat), 's'),
|
||||
expectedLen: rowCount,
|
||||
existsRe: /heating.*time.*flat/i,
|
||||
});
|
||||
}
|
||||
|
||||
function getProductUrl(product: ProductData): string | null {
|
||||
@@ -1972,6 +2266,7 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
// - show constant (non-row) attributes as key/value grid
|
||||
// - show only a small configuration sample + total count
|
||||
// - optionally render full tables with PDF_MODE=full
|
||||
const pdfMode = process.env.PDF_MODE || 'compact'; // 'compact' or 'full'
|
||||
|
||||
// Prefer a curated list that matches website expectations.
|
||||
// IMPORTANT: for row-specific arrays we don't attempt per-row mapping here; we summarize as ranges.
|
||||
@@ -1982,6 +2277,12 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
{ re: /temperature\s*range|operating\s*temperature|betriebstemperatur/i, fallbackLabel: locale === 'de' ? 'Temperaturbereich' : 'Temperature range' },
|
||||
{ re: /bending\s*radius|biegeradius/i, fallbackLabel: locale === 'de' ? 'Biegeradius' : 'Bending radius' },
|
||||
{ re: /cpr\s*class/i, fallbackLabel: locale === 'de' ? 'CPR-Klasse' : 'CPR class' },
|
||||
{ re: /conductor/i, fallbackLabel: locale === 'de' ? 'Leiter' : 'Conductor' },
|
||||
{ re: /insulation/i, fallbackLabel: locale === 'de' ? 'Isolierung' : 'Insulation' },
|
||||
{ re: /sheath/i, fallbackLabel: locale === 'de' ? 'Mantel' : 'Sheath' },
|
||||
{ re: /flame retardant|flammhemmend/i, fallbackLabel: locale === 'de' ? 'Flammhemmend' : 'Flame retardant' },
|
||||
{ re: /packaging|verpackung/i, fallbackLabel: locale === 'de' ? 'Verpackung' : 'Packaging' },
|
||||
{ re: /rohs.*reach/i, fallbackLabel: locale === 'de' ? 'RoHS/REACH' : 'RoHS/REACH' },
|
||||
];
|
||||
|
||||
const picked = new Set<string>();
|
||||
@@ -2145,9 +2446,13 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
return a;
|
||||
};
|
||||
|
||||
// Pull the two most important row-specific columns and show a small excerpt table.
|
||||
// Pull the most important row-specific columns and show a small excerpt table.
|
||||
const rowOuter = findRowAttr(/outer\s*diameter|außen\s*durchmesser|außen-?ø/i);
|
||||
const rowWeight = findRowAttr(/\bweight\b|gewicht/i);
|
||||
const rowDcRes = findRowAttr(/dc resistance|leiterwiderstand/i);
|
||||
const rowCap = findRowAttr(/capacitance|kapazit/i);
|
||||
const rowCurrentAir = findRowAttr(/current.*air/i);
|
||||
const rowCurrentGround = findRowAttr(/current.*ground/i);
|
||||
|
||||
const yAfterCross = drawCrossSectionChipsRow({
|
||||
title: labels.crossSection,
|
||||
@@ -2190,11 +2495,25 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
}
|
||||
|
||||
// Compact per-configuration excerpt (only if it fits).
|
||||
if (rowOuter && rowWeight) {
|
||||
// Build columns dynamically based on what's available
|
||||
const availableColumns: Array<{ key: string; label: string; attr: ProductData['attributes'][number] | null; unit: string }> = [];
|
||||
|
||||
if (rowOuter) availableColumns.push({ key: 'outer', label: locale === 'de' ? 'Außen-Ø' : 'Outer Ø', attr: rowOuter, unit: 'mm' });
|
||||
if (rowWeight) availableColumns.push({ key: 'weight', label: locale === 'de' ? 'Gewicht' : 'Weight', attr: rowWeight, unit: 'kg/km' });
|
||||
if (rowDcRes) availableColumns.push({ key: 'dcres', label: locale === 'de' ? 'Widerstand' : 'Resistance', attr: rowDcRes, unit: 'Ω/km' });
|
||||
if (rowCap) availableColumns.push({ key: 'cap', label: locale === 'de' ? 'Kapazität' : 'Capacitance', attr: rowCap, unit: 'μF/km' });
|
||||
if (rowCurrentAir) availableColumns.push({ key: 'curair', label: locale === 'de' ? 'Strom Luft' : 'Current Air', attr: rowCurrentAir, unit: 'A' });
|
||||
if (rowCurrentGround) availableColumns.push({ key: 'curground', label: locale === 'de' ? 'Strom Erdreich' : 'Current Ground', attr: rowCurrentGround, unit: 'A' });
|
||||
|
||||
if (availableColumns.length >= 2) {
|
||||
// Use first two available columns for the preview table
|
||||
const col1 = availableColumns[0];
|
||||
const col2 = availableColumns[1];
|
||||
|
||||
const previewRows = configRows.map((cfg, i) => ({
|
||||
config: normalizeValue(cfg),
|
||||
col1: formatMaybeWithUnit(getAttrCellValue(rowOuter ?? undefined, i, rowCount), 'mm'),
|
||||
col2: formatMaybeWithUnit(getAttrCellValue(rowWeight ?? undefined, i, rowCount), 'kg/km'),
|
||||
col1: formatMaybeWithUnit(getAttrCellValue(col1.attr ?? undefined, i, rowCount), col1.unit),
|
||||
col2: formatMaybeWithUnit(getAttrCellValue(col2.attr ?? undefined, i, rowCount), col2.unit),
|
||||
}));
|
||||
|
||||
const previewTitle = locale === 'de' ? 'Konfigurationswerte (Auszug)' : 'Configuration values (excerpt)';
|
||||
@@ -2203,8 +2522,8 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
rows: previewRows,
|
||||
headers: {
|
||||
config: locale === 'de' ? 'Konfiguration' : 'Configuration',
|
||||
col1: locale === 'de' ? 'Außen-Ø' : 'Outer Ø',
|
||||
col2: locale === 'de' ? 'Gewicht' : 'Weight',
|
||||
col1: col1.label,
|
||||
col2: col2.label,
|
||||
},
|
||||
getPage: () => page,
|
||||
page,
|
||||
@@ -2221,6 +2540,39 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
|
||||
});
|
||||
if (yAfterPreview >= contentMinY) y = yAfterPreview;
|
||||
}
|
||||
|
||||
// Full table mode: show more technical columns if space allows and mode is enabled
|
||||
if (pdfMode === 'full' && availableColumns.length > 2) {
|
||||
// Try to show additional columns in a chunked table
|
||||
const additionalColumns = availableColumns.slice(2).map(col => ({
|
||||
key: col.key,
|
||||
label: col.label,
|
||||
get: (i: number) => formatMaybeWithUnit(getAttrCellValue(col.attr ?? undefined, i, rowCount), col.unit),
|
||||
}));
|
||||
|
||||
if (additionalColumns.length > 0 && y - 100 >= contentMinY) {
|
||||
y = drawTableChunked({
|
||||
title: locale === 'de' ? 'Technische Daten (alle)' : 'Technical data (all)',
|
||||
configRows,
|
||||
columns: additionalColumns,
|
||||
locale,
|
||||
newPage,
|
||||
getPage: () => page,
|
||||
page,
|
||||
y,
|
||||
margin,
|
||||
contentWidth,
|
||||
contentMinY,
|
||||
font,
|
||||
fontBold,
|
||||
navy,
|
||||
darkGray,
|
||||
lightGray,
|
||||
almostWhite,
|
||||
maxDataColsPerTable: 3,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no cross-section data, do not render the section at all.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user