Add pdf-invoice module: one invoice in OpenPDF 3.0.5, iText Core 9.8.0 and Flying Saucer 10.7.0, Devanagari shaping checked by rendering, streamed vs buffered download, subset sizes and timings

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b6Kg9RWSTJzyz6KP9X
This commit is contained in:
2026-10-30 16:46:25 +00:00
co-authored by Claude Sonnet 5.5
parent 9b1da079c6
commit 3a30194459
54 changed files with 1906 additions and 0 deletions
@@ -0,0 +1,37 @@
package com.ankurm.pdfinvoice;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
/**
* The one invoice all three libraries render. Plain records, no framework types, so each writer
* is a function {@code Invoice -> bytes} and the comparison is about the PDF libraries, not about Spring.
*/
public record Invoice(String number, LocalDate date, Party seller, Party buyer, List<Line> lines, String note) {
public record Party(String name, String address, String gstin) {}
/** {@code description} may be Devanagari; that is the point of the exercise. */
public record Line(String description, int quantity, BigDecimal unitPrice) {
public BigDecimal amount() {
return unitPrice.multiply(BigDecimal.valueOf(quantity));
}
}
/** GST at 18 percent, split evenly into CGST and SGST as an intra-state sale would be. */
public static final BigDecimal GST_RATE = new BigDecimal("0.18");
public BigDecimal subtotal() {
return lines.stream().map(Line::amount).reduce(BigDecimal.ZERO, BigDecimal::add);
}
public BigDecimal gst() {
return subtotal().multiply(GST_RATE).setScale(2, RoundingMode.HALF_UP);
}
public BigDecimal total() {
return subtotal().add(gst());
}
}