Generating PDF invoices with Go and UniDoc
Creating good-looking PDF invoices from your application tends up to be tedious most of the time. You need to deal with different layouts, design, text-positioning, etc., and that’s something most software developers want to avoid.
The most common approach to building PDF files, including invoices, is having an HTML template, filling it up with data, and then converting it to PDF. When converting HTML to PDF, most tools have issues with the PDF layout: margins, page breaks, and text positioning.
By using UniDoc, a comprehensive Golang PDF Library, you’ll be creating beautiful PDF invoices from your Go application with only a few lines of code. The example below creates a simple PDF invoice for Jane Doe, containing five products, notes, logo and pricing details.
import (
"fmt"
"log"
"strconv"
"github.com/unidoc/unidoc/pdf/creator"
"github.com/unidoc/unidoc/pdf/model"
"github.com/unidoc/unidoc/pdf/model/fonts"
)
func main() {
// Instantiate new PDF creator
c := creator.New()
// Create a new PDF page and select it for editing
c.NewPage()
// Create new invoice and populate it with data
invoice := createInvoice(c, "logo.png")
// Write invoice to page
checkErr(c.Draw(invoice))
// Write output file.
// Alternative is writing to a Writer interface by using c.Write
checkErr(c.WriteToFile("simple_invoice.pdf"))
}
func createInvoice(c *creator.Creator, logoPath string) *creator.Invoice {
// Create an instance of Logo used as a header for the invoice
// If the image is not stored localy, you can use NewImageFromData to generate it from byte array
logo, err := c.NewImageFromFile(logoPath)
checkErr(err)
// Create a new invoice
invoice := c.NewInvoice()
// Set invoice logo
invoice.SetLogo(logo)
// Set invoice information
invoice.SetNumber("0001")
invoice.SetDate("28/07/2016")
invoice.SetDueDate("28/07/2016")
invoice.AddInfo("Payment terms", "Due on receipt")
invoice.AddInfo("Paid", "No")
// Set invoice addresses
invoice.SetSellerAddress(&creator.InvoiceAddress{
Name: "John Doe",
Street: "8 Elm Street",
City: "Cambridge",
Zip: "CB14DH",
Country: "United Kingdom",
Phone: "xxx-xxx-xxxx",
Email: "[email protected]",
})
invoice.SetBuyerAddress(&creator.InvoiceAddress{
Name: "Jane Doe",
Street: "9 Elm Street",
City: "London",
Zip: "LB15FH",
Country: "United Kingdom",
Phone: "xxx-xxx-xxxx",
Email: "[email protected]",
})
// Add products to invoice
for i := 1; i < 6; i++ {
invoice.AddLine(
fmt.Sprintf("Test product #%d", i),
"1",
strconv.Itoa((i-1)*7),
strconv.Itoa((i+4)*3),
)
}
// Set invoice totals
invoice.SetSubtotal("$100.00")
invoice.AddTotalLine("Tax (10%)", "$10.00")
invoice.AddTotalLine("Shipping", "$5.00")
invoice.SetTotal("$115.00")
// Set invoice content sections
invoice.SetNotes("Notes", "Thank you for your business.")
invoice.SetTerms("Terms and conditions", "Full refund for 60 days after purchase.")
return invoice
}
Upon execution, the following PDF file will be generated:
You can download the PDF file from the above example here.
The above example demonstrated creating a simple PDF invoice. A very similar example is available as a test file here.
The generated invoice is highly customizable. Things like text formatting (font, color, size), page styling and size are easily changeable.
The following function manipulates various parts of the invoice:
func customizeInvoice(i *creator.Invoice) {
// Load custom font
fontHelvetica := model.NewStandard14FontMustCompile(fonts.HelveticaName)
// Create colors from RGB
lightBlue := creator.ColorRGBFrom8bit(217, 240, 250)
red := creator.ColorRGBFrom8bit(225, 0, 0)
// Set invoice title text style
i.SetTitleStyle(creator.TextStyle{
Color: red,
Font: fontHelvetica,
FontSize: 32,
})
// Set invoice address heading style
i.SetAddressHeadingStyle(creator.TextStyle{
Font: fontHelvetica,
Color: red,
FontSize: 16,
})
// Set columns and rows styling
// Line formatting can be changed immediately after adding a line
for cn, col := range i.Columns() {
col.BackgroundColor = lightBlue
col.BorderColor = lightBlue
col.TextStyle.FontSize = 9
col.Alignment = creator.CellHorizontalAlignmentCenter
for _, line := range i.Lines() {
line[cn].BorderColor = lightBlue
line[cn].TextStyle.FontSize = 9
line[cn].Alignment = creator.CellHorizontalAlignmentCenter
}
}
// Change Total text syle
titleCell, contentCell := i.Total()
titleCell.BackgroundColor = lightBlue
titleCell.BorderColor = lightBlue
contentCell.BackgroundColor = lightBlue
contentCell.BorderColor = lightBlue
// Set Note text style
i.SetNoteHeadingStyle(creator.TextStyle{
Color: red,
Font: fontHelvetica,
FontSize: 16,
})
}
The code for manipulating invoice styling could be done in createInvoice func as well. Upon execution, following invoice is generated:
Thus, customized invoice generation is quite easy to do with UniDoc. If you have any further requirements please raise an issue on UniDoc’s GitHub repository and we will gladly assist you with it.