Takumi

Invoices

Render invoice line items and attach structured invoice data.

Render line items and totals as a paged document. If your invoice format requires embedded XML, add it as an attachment with the required PDF/A and XMP settings.

A plain invoice

Line items flow across pages. A footer carries the page counter. measure returns the band's height, so the bottom margin always clears it:

import {  } from "@takumi-rs/helpers";
import { ,  } from "takumi-pdf";
import { ,  } from "takumi-pdf/primitives";

const  = (
  < ="flex w-full justify-between px-12 text-[10px] text-[#6b7280]">
    <>Invoice {.}</>
    < ="flex">
      Page < /> of < />
    </>
  </>
);

const  = await (["Inter"]);
const {  } = await (, { : "a4",  });

const  = await (< ={} />, {
  : "a4",
  : { : 48, :  + 32, : 48, : 48 },
  ,
  ,
});

Use break-inside: avoid to keep a line item together when it fits on a page. In Tailwind, use break-inside-avoid:

import "takumi-pdf";

< ="flex break-inside-avoid gap-3 pt-3 text-xs">
  < ="flex-1">{.}</>
  < ="w-[100px] text-right">{.}</>
</>;

Apply the same style to the totals block.

Electronic invoices

Factur-X and ZUGFeRD combine a readable PDF invoice with structured XML. Configure the container for the profile you are implementing:

The standard requiresThe option
A PDF/A-3 containerpdfa: "3b"
The XML attached by nameattachments
An fx: XMP blockmetadata.xmp
A modification date per filemodificationDate
Embedded subset fontsalways on

Each attachment's modificationDate falls back to metadata.creationDate. Setting the document date once covers both.

import {  } from "takumi-pdf";

const  = await (, {
  : "en",
  : "3b",
  : "ua1",
  : {
    : "Invoice INV-2026-0042",
    : "2026-08-06",
    : [],
  },
  : [
    {
      : "factur-x.xml",
      : ,
      : "text/xml",
      : "Factur-X 1.0 MINIMUM invoice data",
      : "data",
    },
  ],
});

The renderer checks PDF conformance while writing. It does not validate invoice XML, tax rules, or acceptance by a receiving system.

Takumi does not build the invoice XML. Use a library for the profile, or emit the elements the profile lists. The e-invoice example writes a MINIMUM profile by hand.

Validating the result

Two validators cover the two halves. Both need Java.

veraPDF checks the container:

verapdf --flavour 3b --format text invoice.pdf
verapdf --flavour ua1 --format text invoice.pdf

Mustang checks the Factur-X half, both the XML and the packaging:

java -jar Mustang-CLI.jar --action validate --source invoice.pdf

Mustang finds the profile through the fx: XMP block. Takumi writes the values and the schema description PDF/A demands, so the two cannot drift. It does not check the values: a wrong profile name surfaces in Mustang, not at render time.

Accessible invoices

For PDF/UA-1 output, set tagged: "ua1" and supply the required metadata. Review the reading order and table semantics as well. See PDF/A and PDF/UA.

Reproducible bytes

Use a fixed metadata.creationDate with the same content, resources, and renderer version when you need reproducible bytes. A new date changes the file even if the invoice looks the same.

Last updated on

On this page