From d0654af33950942c38bbd0dadd5ea62bab3eac95 Mon Sep 17 00:00:00 2001 From: Jakob Date: Mon, 23 Mar 2026 11:12:28 +0100 Subject: [PATCH] Fix PDF generation with simplified HTML Use simpler HTML structure compatible with printpdf renderer. Use inline styles and standard table elements for better rendering. --- src/pdf.rs | 271 ++++++++++++++++------------------------------------- 1 file changed, 80 insertions(+), 191 deletions(-) diff --git a/src/pdf.rs b/src/pdf.rs index 4d557e6..9dc901e 100644 --- a/src/pdf.rs +++ b/src/pdf.rs @@ -14,145 +14,68 @@ pub fn generate_customer_pdf( ) -> Result<(), Box> { let html = format!( r#" - + - - Faktura - Kund {} - + + -
-
-

Faktura - Kund {}

-
Period: {}
-
-
-
Genererad: {}
-
-
+
+

Faktura - Kund {customer_num}

+
Period: {period} | Genererad: {gen_date}
+
-
-

Sammanfattning

- - - - - - - - - - - {} - - - - - - - -
ProduktVolym (L)BeloppSnittpris/L
Totalt{}{} Kr
-
+

Sammanfattning

+ + +{products} + +
ProduktVolym (L)BeloppSnittpris/L
Totalt{total_vol}{total_amt} Kr
- {} +{cards} + +
Totalsumma: {grand_total} Kr
"#, - customer.customer_number, - customer.customer_number, - period, - generated_date, - generate_product_rows(&customer.summary.products), - customer.summary.total_volume, - customer.summary.grand_total, - generate_card_sections(&customer.cards), + customer_num = customer.customer_number, + period = period, + gen_date = generated_date, + products = generate_products_table(&customer.summary.products), + total_vol = customer.summary.total_volume, + total_amt = customer.summary.grand_total, + cards = generate_cards(&customer.cards), + grand_total = customer.summary.grand_total, ); let mut warnings = Vec::new(); - let doc = PdfDocument::from_html( + let doc = match PdfDocument::from_html( &html, &BTreeMap::new(), &BTreeMap::new(), &GeneratePdfOptions::default(), &mut warnings, - )?; + ) { + Ok(d) => d, + Err(e) => { + eprintln!("PDF generation warning: {}", e); + return Err(e.into()); + } + }; let file = File::create(output_path)?; let mut writer = BufWriter::new(file); @@ -162,83 +85,49 @@ pub fn generate_customer_pdf( Ok(()) } -fn generate_product_rows(products: &[crate::ProductSummary]) -> String { +fn generate_products_table(products: &[crate::ProductSummary]) -> String { products .iter() - .map(|p| { - format!( - r#" - {} - {} - {} Kr - {} Kr - "#, - p.name, p.volume, p.amount, p.avg_price - ) - }) + .map(|p| format!( + "{}{}{} Kr{} Kr", + p.name, p.volume, p.amount, p.avg_price + )) .collect::>() - .join("\n ") + .join("\n") } -fn generate_card_sections(cards: &[crate::CardData]) -> String { +fn generate_cards(cards: &[crate::CardData]) -> String { cards .iter() - .map(|card| { - format!( - r#"
-
Kort: {} | {} transaktioner
-
Summa: {} Kr | Volym: {} L
- - - - - - - - - - - - - {} - - - - - - - -
DatumProduktPris/LVolymBeloppKvitto
Kortsumma{}{}
-
"#, - card.card_number, - card.transactions.len(), - card.total_amount, - card.total_volume, - generate_transaction_rows(&card.transactions), - card.total_volume, - card.total_amount, - ) - }) + .map(|card| format!( + r#"
+
Kort: {} ({} transaktioner)
+ + + +{} + +
DatumProduktPris/LVolymBeloppKvitto
Kortsumma{}{}
+
"#, + card.card_number, + card.transactions.len(), + card.total_amount, + card.total_volume, + generate_transactions(&card.transactions), + card.total_volume, + card.total_amount, + )) .collect::>() - .join("\n\n ") + .join("\n") } -fn generate_transaction_rows(transactions: &[crate::FormattedTransaction]) -> String { - transactions +fn generate_transactions(txs: &[crate::FormattedTransaction]) -> String { + txs .iter() - .map(|tx| { - format!( - r#" - {} - {} - {} - {} - {} - {} - "#, - tx.date, tx.quality_name, tx.price, tx.volume, tx.amount, tx.receipt - ) - }) + .map(|tx| format!( + "{}{}{}{}{}{}", + tx.date, tx.quality_name, tx.price, tx.volume, tx.amount, tx.receipt + )) .collect::>() - .join("\n ") + .join("\n") }