print-server: printing invoices through a spool
examples/print-server — a small business application that prints invoices. It fills an invoice template with what is typed on its page, puts the document in the queue of a print server it embeds, and shows each job as the spool sends it and the printer prints it. The page answers at once; the printing happens behind it, and survives a restart.
cd examples/print-server
go run . -fake-printer # prints on bdf's fake IPP printer, in the same process
open http://127.0.0.1:8083/
go run . -printer ipps://printer.example.local/ipp/print # on a printer of the network
What the server does
- Fills the template.
POST /invoicesreads the customer, the items (a line each: name, quantity, price), a note and the user, and fillsconverter/xlsx/testdata/form-rows.xlsxwith them (form.Fill): an Excel workbook whose tags ({{no}},{{customer}},{{#items}}…{{/items}}) take the data, laid out as the pages Excel prints. The result is a.bdfin memory. - Puts it in the queue. The application opens a print server from a configuration it writes itself (one printer, one queue
invoiceswhose defaults print on both sides), withserver.New, and submits the document withSpool().Submit, for the user the page names. It does not wait for the printer. - Shares the API. The print server's
http.Handleris mounted under/api/: the page reads/api/v1/jobsand follows/api/v1/events, andbdf jobs -server http://127.0.0.1:8083works on the same jobs. - Keeps the jobs. The spool is
data/spool.db. Stop the program while a job is being sent and run it again: the job is checked against the printer and printed once.
Why this shape
A business system that prints should not hold a request open until the printer is done, nor lose a job because the printer was off. Embedding the print server gives the application the spool's guarantees (one file, retries, no job printed twice, accounting) without another process; a larger site runs bdf printd on its own and talks to it with print/server/client or plain HTTP, as curl does.