Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -258,39 +258,42 @@ async function create() {
|
||||
const fieldWidth2 = 380
|
||||
const labelOffset = 0
|
||||
// place SEPA inputs 1cm left (≈28.35pt) from previous and slightly up; adjust to align with labels
|
||||
const inputX = sepaLeft + 220 - 28.35
|
||||
// reduce vertical raise so inputs sit on same baseline as labels (previously too high)
|
||||
const inputYAdjust = 6
|
||||
const inputX = sepaLeft + 220 - 28.35
|
||||
// reduce vertical raise so inputs sit on same baseline as labels (previously too high)
|
||||
const inputYAdjust = 6 + 5.67 // Move SEPA inputs (except date) up by additional 2mm (≈5.67pt)
|
||||
// adjust page2DownShift so inputs move up by 0.75mm (net)
|
||||
// 0.75mm = 0.075cm -> ~2.12625 pt
|
||||
const page2DownShift = 0.075 * 28.35 // 0.075 cm -> ~2.12625 pt
|
||||
|
||||
// apply labelsShift only to the SEPA form labels/inputs so paragraphs remain unaffected
|
||||
let syFields = sy + labelsShift
|
||||
page2.drawText('Mitglied (Vorname und Name)', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_mitglied').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_mitglied').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('Kontoinhaber (Vorname und Name):', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_kontoinhaber').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_kontoinhaber').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('Straße und Hausnummer:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_strasse').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_strasse').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('PLZ und Ort:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_plz_ort').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_plz_ort').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('Kreditinstitut:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_bank').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_bank').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('IBAN:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
form.createTextField('sepa_iban').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_iban').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
page2.drawText('BIC:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
|
||||
// BIC remains full width as requested
|
||||
form.createTextField('sepa_bic').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: 220, height: fieldHeight2, font: helv })
|
||||
form.createTextField('sepa_bic').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: 220, height: fieldHeight2, font: helv })
|
||||
syFields -= lineGap * 1.1
|
||||
|
||||
// add signature and date lines 2cm below last field
|
||||
@@ -444,6 +447,66 @@ Das Vereinsmitglied trifft die Entscheidung zur Veröffentlichung seiner Daten i
|
||||
py = drawWrappedOnPage3('folgende allgemeine Daten zu meiner Person:', leftX, py, normalSize, helv)
|
||||
py -= blockSpacing
|
||||
|
||||
// Rebuild a simple, single-column, non-overlapping form area on page 3
|
||||
const formLeft = leftX
|
||||
const formFieldW = 360
|
||||
const formFieldH = 14
|
||||
const formGap = 22
|
||||
// start a bit lower to separate from the block text
|
||||
py -= 28
|
||||
// Row layout
|
||||
const colGap = 220
|
||||
// Shifts (in points): 1 cm = ~28.35 pt
|
||||
const leftColShift = 0.3 * 28.35 // 0.3 cm -> ~8.505 pt
|
||||
const vornameLabelShift = 1.0 * 28.35 // 1.0 cm -> ~28.35 pt
|
||||
const vornameFieldShift = 1.3 * 28.35 // 1.3 cm -> ~36.855 pt
|
||||
const leftColX = formLeft + leftColShift
|
||||
const rightColX = formLeft + colGap
|
||||
|
||||
// Row 1: Name (left) and Vorname (right)
|
||||
// Keep the left label at the original formLeft, move only the input field slightly right by 0.1cm
|
||||
const leftInputShift = 0.35 * 28.35 // 0.35 cm -> ~9.9225 pt
|
||||
// extra small horizontal nudge for all non-date inputs: 1mm
|
||||
const extraHShift = 0.1 * 28.35 // 0.1 cm (1 mm) -> ~2.835 pt
|
||||
// vertical shift for all input fields (including date): 0.6 cm up
|
||||
const verticalFieldShift = 0.6 * 28.35 // 0.6 cm -> ~17.01 pt
|
||||
// downward nudge for non-date inputs requested now: 0.2 cm -> ~5.67 pt
|
||||
const nonDateDownShift = 0.2 * 28.35 // 0.2 cm -> ~5.67 pt
|
||||
page3.drawText('Name:', { x: formLeft, y: py, size: normalSize, font: helv })
|
||||
form.createTextField('page3_name').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
|
||||
// Vorname label and field moved further right as requested
|
||||
page3.drawText('Vorname:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
|
||||
form.createTextField('page3_vorname').addToPage(page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
|
||||
py -= formGap
|
||||
// Anschrift (full width)
|
||||
page3.drawText('Anschrift:', { x: formLeft, y: py, size: normalSize, font: helv })
|
||||
form.createTextField('page3_anschrift').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: formFieldW + 40, height: formFieldH, font: helv })
|
||||
py -= formGap
|
||||
// Row 3: Telefonnummer (left) and E-Mail (right)
|
||||
// Keep left label at formLeft, shift only the input field by leftInputShift
|
||||
page3.drawText('Telefonnummer:', { x: formLeft, y: py, size: normalSize, font: helv })
|
||||
form.createTextField('page3_telefon').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
|
||||
page3.drawText('E-Mail-Adresse:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
|
||||
form.createTextField('page3_email').addToPage(page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 180, height: formFieldH, font: helv })
|
||||
py -= formGap
|
||||
// remove fax field/label per request (space preserved)
|
||||
py -= formGap
|
||||
py -= formGap
|
||||
// Date and signature line
|
||||
const dateFieldW = 120
|
||||
page3.drawText('Frankfurt/Main-Harheim, den', { x: formLeft, y: py, size: normalSize, font: helv })
|
||||
const dateX = formLeft + helv.widthOfTextAtSize('Frankfurt/Main-Harheim, den ', normalSize)
|
||||
// date field also moves up by verticalFieldShift (but not horizontally shifted by extraHShift)
|
||||
// now move the date and signature line 0.2cm down as requested
|
||||
const dateFieldY = py - formFieldH + verticalFieldShift - nonDateDownShift
|
||||
form.createTextField('page3_datum').addToPage(page3, { x: dateX, y: dateFieldY, width: dateFieldW, height: formFieldH, font: helv })
|
||||
// signature line starts directly under the (moved) date field
|
||||
page3.drawRectangle({ x: dateX, y: dateFieldY - 6, width: 300, height: 1, color: rgb(0,0,0) })
|
||||
// label under signature line
|
||||
const sigLabel = 'Datum, Unterschrift (bei Jugendlichen gesetzlicher Vertreter)'
|
||||
const sigLabelSize = 10
|
||||
page3.drawText(sigLabel, { x: dateX, y: dateFieldY - 18, size: sigLabelSize, font: helv })
|
||||
|
||||
const pdfBytes = await pdfDoc.save()
|
||||
fs.writeFileSync('server/templates/mitgliedschaft-fillable.pdf', pdfBytes)
|
||||
console.log('Wrote server/templates/mitgliedschaft-fillable.pdf')
|
||||
|
||||
100
scripts/fill-sample-template.js
Normal file
100
scripts/fill-sample-template.js
Normal file
@@ -0,0 +1,100 @@
|
||||
import fs from 'fs'
|
||||
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
|
||||
|
||||
async function fill() {
|
||||
const templatePath = 'server/templates/mitgliedschaft-fillable.pdf'
|
||||
if (!fs.existsSync(templatePath)) {
|
||||
console.error('Template not found:', templatePath)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const existingPdfBytes = fs.readFileSync(templatePath)
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes)
|
||||
const form = pdfDoc.getForm()
|
||||
|
||||
// Simple sample data
|
||||
const sample = {
|
||||
nachname: 'Müller',
|
||||
vorname: 'Anna',
|
||||
strasse: 'Hauptstr. 12',
|
||||
plz_ort: '60389 Frankfurt',
|
||||
geburtsdatum: '01.01.1990',
|
||||
telefon: '069 123456',
|
||||
email: 'anna.mueller@example.de',
|
||||
telefon_mobil: '0151 2345678',
|
||||
mitglied_aktiv: true,
|
||||
mitglied_passiv: false,
|
||||
sepa_mitglied: 'Anna Müller',
|
||||
sepa_kontoinhaber: 'Anna Müller',
|
||||
sepa_strasse: 'Hauptstr. 12',
|
||||
sepa_plz_ort: '60389 Frankfurt',
|
||||
sepa_bank: 'Sparkasse',
|
||||
sepa_iban: 'DE00123456781234567890',
|
||||
sepa_bic: 'PBNKDEFF',
|
||||
sepa_datum: '23.10.2025',
|
||||
sign_datum: '23.10.2025',
|
||||
page3_name: 'Müller',
|
||||
page3_vorname: 'Anna',
|
||||
page3_anschrift: 'Hauptstr. 12, 60389 Frankfurt',
|
||||
page3_telefon: '069 123456',
|
||||
page3_fax: '069 654321',
|
||||
page3_email: 'anna.mueller@example.de',
|
||||
page3_datum: '23.10.2025'
|
||||
}
|
||||
|
||||
function safeSetText(name, value) {
|
||||
try {
|
||||
const f = form.getTextField(name)
|
||||
f.setText(value)
|
||||
} catch (e) {
|
||||
// ignore missing fields
|
||||
}
|
||||
}
|
||||
|
||||
safeSetText('nachname', sample.nachname)
|
||||
safeSetText('vorname', sample.vorname)
|
||||
safeSetText('strasse', sample.strasse)
|
||||
safeSetText('plz_ort', sample.plz_ort)
|
||||
safeSetText('geburtsdatum', sample.geburtsdatum)
|
||||
safeSetText('telefon', sample.telefon)
|
||||
safeSetText('email', sample.email)
|
||||
safeSetText('telefon_mobil', sample.telefon_mobil)
|
||||
|
||||
try {
|
||||
const cbA = form.getCheckBox('mitglied_aktiv')
|
||||
if (sample.mitglied_aktiv) cbA.check(); else cbA.uncheck()
|
||||
} catch(e) {}
|
||||
try {
|
||||
const cbP = form.getCheckBox('mitglied_passiv')
|
||||
if (sample.mitglied_passiv) cbP.check(); else cbP.uncheck()
|
||||
} catch(e) {}
|
||||
|
||||
safeSetText('sepa_mitglied', sample.sepa_mitglied)
|
||||
safeSetText('sepa_kontoinhaber', sample.sepa_kontoinhaber)
|
||||
safeSetText('sepa_strasse', sample.sepa_strasse)
|
||||
safeSetText('sepa_plz_ort', sample.sepa_plz_ort)
|
||||
safeSetText('sepa_bank', sample.sepa_bank)
|
||||
safeSetText('sepa_iban', sample.sepa_iban)
|
||||
safeSetText('sepa_bic', sample.sepa_bic)
|
||||
safeSetText('sepa_datum', sample.sepa_datum)
|
||||
safeSetText('sign_datum', sample.sign_datum)
|
||||
|
||||
// page3 fields
|
||||
safeSetText('page3_name', sample.page3_name)
|
||||
safeSetText('page3_vorname', sample.page3_vorname)
|
||||
safeSetText('page3_anschrift', sample.page3_anschrift)
|
||||
safeSetText('page3_telefon', sample.page3_telefon)
|
||||
safeSetText('page3_fax', sample.page3_fax)
|
||||
safeSetText('page3_email', sample.page3_email)
|
||||
safeSetText('page3_datum', sample.page3_datum)
|
||||
|
||||
// flatten all fields
|
||||
try { form.flatten() } catch (e) {}
|
||||
|
||||
const out = await pdfDoc.save()
|
||||
if (!fs.existsSync('temp')) fs.mkdirSync('temp')
|
||||
fs.writeFileSync('temp/mitgliedschaft-sample-filled.pdf', out)
|
||||
console.log('Wrote temp/mitgliedschaft-sample-filled.pdf')
|
||||
}
|
||||
|
||||
fill().catch(e => { console.error(e); process.exit(1) })
|
||||
Binary file not shown.
BIN
temp/mitgliedschaft-sample-filled.pdf
Normal file
BIN
temp/mitgliedschaft-sample-filled.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user