Help us shape the future of Go! Take the 2026 Go Developer Survey

generator

package module
v0.0.0-...-5a721ee Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

golangci-lint Go Report Card GoDoc

Golang invoice generator

A super fast golang package to generate invoices, delivery notes and quotations as pdf using https://github.com/go-pdf/fpdf.

This project is a fork of angelodlfrtr/go-invoice-generator, distributed under the same Apache License 2.0. See NOTICE for the original copyright notice. All credit for the original design and implementation goes to the upstream authors and contributors; this fork adds/customizes features on top of that base.

Features

  • Generate PDF invoices, delivery notes, and quotations
  • Support for Code 128 barcodes
  • Customizable styling and colors
  • Multi-language support
  • Automatic calculations (tax, discounts, totals)
  • Logo support
  • Header and footer customization
  • Optional tax display trigger (IsTaxDisplay)
  • Shipping fee row in totals

Download from Github

go get -u github.com/tuanhuu3264/tuan-invoice

Example output

DeliveryNoteExample

Quick start

package main

import (
	"io/ioutil"
	"testing"

	generator "github.com/tuanhuu3264/tuan-invoice"
)
With Barcode Support
// Create document with barcode
doc, _ := generator.New(generator.Invoice, &generator.Options{
	TextTypeInvoice: "FACTURE",
	AutoPrint:       true,
})

// Set barcode content (Code 128 format)
doc.SetBarCode("INV-2024-001")

// Build and save
pdf, _ := doc.Build()
pdf.OutputFileAndClose("invoice_with_barcode.pdf")

func TestNew(t *testing.T) { doc, _ := generator.New(generator.Invoice, &generator.Options{ TextTypeInvoice: "FACTURE", AutoPrint: true, })

doc.SetHeader(&generator.HeaderFooter{
	Text:       "<center>Cupcake ipsum dolor sit amet bonbon. I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder.</center>",
	Pagination: true,
})

doc.SetFooter(&generator.HeaderFooter{
	Text:       "<center>Cupcake ipsum dolor sit amet bonbon. I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder.</center>",
	Pagination: true,
})

doc.SetRef("testref")
doc.SetVersion("someversion")

doc.SetDescription("A description")
doc.SetNotes("I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder! I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder! I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder! I love croissant cotton candy. Carrot cake sweet I love sweet roll cake powder! ")

doc.SetDate("02/03/2021")
doc.SetPaymentTerm("02/04/2021")

logoBytes, err := ioutil.ReadFile("./example_logo.png")
if err != nil {
	log.Fatal(err)
}

doc.SetCompany(&generator.Contact{
	Name: "Test Company",
	Logo: logoBytes,
	Address: &generator.Address{
		Address:    "89 Rue de Brest",
		Address2:   "Appartement 2",
		PostalCode: "75000",
		City:       "Paris",
		Country:    "France",
	},
})

doc.SetCustomer(&generator.Contact{
	Name: "Test Customer",
	Address: &generator.Address{
		Address:    "89 Rue de Paris",
		PostalCode: "29200",
		City:       "Brest",
		Country:    "France",
	},
})

for i := 0; i < 3; i++ {
	doc.AppendItem(&generator.Item{
		Name:        "Cupcake ipsum dolor sit amet bonbon, coucou bonbon lala jojo, mama titi toto",
		Description: "Cupcake ipsum dolor sit amet bonbon, Cupcake ipsum dolor sit amet bonbon, Cupcake ipsum dolor sit amet bonbon",
		UnitCost:    "99876.89",
		Quantity:    "2",
		Tax: &generator.Tax{
			Percent: "20",
		},
	})
}

doc.AppendItem(&generator.Item{
	Name:     "Test",
	UnitCost: "99876.89",
	Quantity: "2",
	Tax: &generator.Tax{
		Amount: "89",
	},
	Discount: &generator.Discount{
		Percent: "30",
	},
})

doc.AppendItem(&generator.Item{
	Name:     "Test",
	UnitCost: "3576.89",
	Quantity: "2",
	Discount: &generator.Discount{
		Percent: "50",
	},
})

doc.AppendItem(&generator.Item{
	Name:     "Test",
	UnitCost: "889.89",
	Quantity: "2",
	Discount: &generator.Discount{
		Amount: "234.67",
	},
})

doc.SetDefaultTax(&generator.Tax{
	Percent: "10",
})

// doc.SetDiscount(&generator.Discount{
// Percent: "90",
// })
doc.SetDiscount(&generator.Discount{
	Amount: "1340",
})

// Optional shipping fee doc.SetShippingFee("30000")

pdf, err := doc.Build()
if err != nil {
	log.Fatal(err)
}

err = pdf.OutputFileAndClose("out.pdf")

if err != nil {
	log.Fatal(err)
}

}


## Tax display trigger

Use `IsTaxDisplay` in `Options` to control tax visibility:

- `IsTaxDisplay: true` (default): show tax row and include tax in grand total
- `IsTaxDisplay: false`: hide tax row and calculate grand total without tax

```go
doc, _ := generator.New(generator.Invoice, &generator.Options{
	IsTaxDisplay:         false,
	TextTotalShippingFee: "Phí vận chuyển",
})

doc.SetShippingFee("50000")

Credits

This project is a fork of angelodlfrtr/go-invoice-generator. Full credit for the original work goes to that project's author and contributors.

License

This SDK is distributed under the Apache License, Version 2.0, see LICENSE and NOTICE for more information.

Documentation

Overview

Package generator allows you to easily generate invoices, delivery notes and quotations in GoLang.

Index

Constants

View Source
const (
	// Invoice define the "invoice" document type
	Invoice string = "INVOICE"

	// Quotation define the "quotation" document type
	Quotation string = "QUOTATION"

	// DeliveryNote define the "delievry note" document type
	DeliveryNote string = "DELIVERY_NOTE"

	// BaseMargin define base margin used in documents
	BaseMargin float64 = 10

	// BaseMarginTop define base margin top used in documents
	BaseMarginTop float64 = 20

	// HeaderMarginTop define base header margin top used in documents
	HeaderMarginTop float64 = 5

	// MaxPageHeight define the maximum height for a single page
	MaxPageHeight float64 = 260
)
View Source
const (
	// ItemColNameOffset ...
	ItemColNameOffset float64 = 10

	// ItemColUnitPriceOffset ...
	ItemColUnitPriceOffset float64 = 80

	// ItemColQuantityOffset ...
	ItemColQuantityOffset float64 = 103

	// ItemColTotalHTOffset ...
	ItemColTotalHTOffset float64 = 113

	// ItemColDiscountOffset ...
	ItemColDiscountOffset float64 = 140

	// ItemColTaxOffset ...
	ItemColTaxOffset float64 = 157

	// ItemColTotalTTCOffset ...
	ItemColTotalTTCOffset float64 = 175
)

Cols offsets

View Source
const (
	DiscountTypeAmount  string = "amount"
	DiscountTypePercent string = "percent"
)

Discount types

View Source
const (
	TaxTypeAmount  string = "amount"
	TaxTypePercent string = "percent"
)

Tax types

Variables

View Source
var (
	// BaseTextFontSize define the base font size for text in document
	BaseTextFontSize float64 = 10

	// SmallTextFontSize define the small font size for text in document
	SmallTextFontSize float64 = 8

	// ExtraSmallTextFontSize define the extra small font size for text in document
	ExtraSmallTextFontSize float64 = 9

	// LargeTextFontSize define the large font size for text in document
	LargeTextFontSize float64 = 13
)
View Source
var ErrInvalidDiscount = errors.New("invalid discount")

ErrInvalidDiscount when percent and amount are empty

View Source
var ErrInvalidDocumentType = errors.New("invalid document type")
View Source
var ErrInvalidTax = errors.New("invalid tax")

ErrInvalidTax when percent and amount are empty

Functions

This section is empty.

Types

type Address

type Address struct {
	Address    string `json:"address,omitempty" validate:"required"`
	Address2   string `json:"address_2,omitempty"`
	PostalCode string `json:"postal_code,omitempty"`
	City       string `json:"city,omitempty"`
	Country    string `json:"country,omitempty"`
}

Address represent an address

func (*Address) ToString

func (a *Address) ToString() string

ToString output address as string Line break are added for new lines

type Contact

type Contact struct {
	Name           string   `json:"name,omitempty" validate:"required,min=1,max=256"`
	Address        *Address `json:"address,omitempty"`
	Phone          string   `json:"phone,omitempty"`
	AddtionnalInfo []string `json:"additional_info,omitempty"`
}

Contact contact a company informations

type Discount

type Discount struct {
	Percent string `json:"percent,omitempty"` // Discount in percent ex 17
	Amount  string `json:"amount,omitempty"`  // Discount in amount ex 123.40
	// contains filtered or unexported fields
}

Discount define discount as percent or fixed amount

func (*Discount) Prepare

func (d *Discount) Prepare() error

Prepare convert strings to decimal

type Document

type Document struct {
	Options      *Options      `json:"options,omitempty"`
	Header       *HeaderFooter `json:"header,omitempty"`
	Footer       *HeaderFooter `json:"footer,omitempty"`
	Type         string        `json:"type,omitempty" validate:"required,oneof=INVOICE DELIVERY_NOTE QUOTATION"`
	Ref          string        `json:"ref,omitempty" validate:"required,min=1,max=32"`
	Version      string        `json:"version,omitempty" validate:"max=32"`
	ClientRef    string        `json:"client_ref,omitempty" validate:"max=64"`
	Description  string        `json:"description,omitempty" validate:"max=1024"`
	Notes        string        `json:"notes,omitempty"`
	BarCode      string        `json:"barcode,omitempty"`
	Company      *Contact      `json:"company,omitempty" validate:"required"`
	Customer     *Contact      `json:"customer,omitempty" validate:"required"`
	Items        []*Item       `json:"items,omitempty"`
	Date         string        `json:"date,omitempty"`
	ValidityDate string        `json:"validity_date,omitempty"`
	PaymentTerm  string        `json:"payment_term,omitempty"`
	DefaultTax   *Tax          `json:"default_tax,omitempty"`
	Discount     *Discount     `json:"discount,omitempty"`
	ShippingFee  string        `json:"shipping_fee,omitempty"`
	// contains filtered or unexported fields
}

Document define base document

func New

func New(docType string, options *Options) (*Document, error)

New return a new documents with provided types and defaults

func (*Document) AppendItem

func (d *Document) AppendItem(item *Item) *Document

AppendItem to document items

func (*Document) Build

func (doc *Document) Build() (*fpdf.Fpdf, error)

Build pdf document from data provided

func (*Document) GrandTotal

func (doc *Document) GrandTotal() decimal.Decimal

GrandTotal returns the final payable total based on display options.

func (*Document) Pdf

func (doc *Document) Pdf() *fpdf.Fpdf

Pdf returns the underlying *fpdf.Fpdf used to build document

func (*Document) SetBarCode

func (d *Document) SetBarCode(barcode string) *Document

SetBarCode of document

func (*Document) SetCompany

func (d *Document) SetCompany(company *Contact) *Document

SetCompany of document

func (*Document) SetCustomer

func (d *Document) SetCustomer(customer *Contact) *Document

SetCustomer of document

func (*Document) SetDate

func (d *Document) SetDate(date string) *Document

SetDate of document

func (*Document) SetDefaultTax

func (d *Document) SetDefaultTax(tax *Tax) *Document

SetDefaultTax of document

func (*Document) SetDescription

func (d *Document) SetDescription(desc string) *Document

SetDescription of document

func (*Document) SetDiscount

func (d *Document) SetDiscount(discount *Discount) *Document

SetDiscount of document

func (*Document) SetFooter

func (d *Document) SetFooter(footer *HeaderFooter) *Document

SetFooter set footer of document

func (*Document) SetHeader

func (d *Document) SetHeader(header *HeaderFooter) *Document

SetHeader set header of document

func (*Document) SetNotes

func (d *Document) SetNotes(notes string) *Document

SetNotes of document

func (*Document) SetPaymentTerm

func (d *Document) SetPaymentTerm(term string) *Document

SetPaymentTerm of document

func (*Document) SetRef

func (d *Document) SetRef(ref string) *Document

SetRef of document

func (*Document) SetShippingFee

func (d *Document) SetShippingFee(shippingFee string) *Document

SetShippingFee of document

func (*Document) SetType

func (d *Document) SetType(docType string) *Document

SetType set type of document

func (*Document) SetUnicodeTranslator

func (doc *Document) SetUnicodeTranslator(fn UnicodeTranslateFunc)

SetUnicodeTranslator to use See https://pkg.go.dev/github.com/go-pdf/fpdf#UnicodeTranslator

func (*Document) SetVersion

func (d *Document) SetVersion(version string) *Document

SetVersion of document

func (*Document) Tax

func (doc *Document) Tax() decimal.Decimal

Tax return the total tax with document discount

func (*Document) TotalWithTax

func (doc *Document) TotalWithTax() decimal.Decimal

TotalWithTax return total with tax and with document discount

func (*Document) TotalWithoutTax

func (doc *Document) TotalWithoutTax() decimal.Decimal

TotalWithoutTax return total without tax and with document discount

func (*Document) TotalWithoutTaxAndWithoutDocumentDiscount

func (doc *Document) TotalWithoutTaxAndWithoutDocumentDiscount() decimal.Decimal

TotalWithoutTaxAndWithoutDocumentDiscount return total without tax and without document discount

func (*Document) Validate

func (d *Document) Validate() error

Validate document fields

type HeaderFooter

type HeaderFooter struct {
	UseCustomFunc bool    `json:"-"`
	Text          string  `json:"text,omitempty"`
	FontSize      float64 `json:"font_size,omitempty" default:"10"`
	Pagination    bool    `json:"pagination,omitempty"`
}

HeaderFooter define header or footer informations on document

func (*HeaderFooter) ApplyFunc

func (hf *HeaderFooter) ApplyFunc(pdf *fpdf.Fpdf, fn fnc)

ApplyFunc allow user to apply custom func

type Item

type Item struct {
	Name        string    `json:"name,omitempty" validate:"required"`
	Description string    `json:"description,omitempty"`
	UnitCost    string    `json:"unit_cost,omitempty"`
	Quantity    string    `json:"quantity,omitempty"`
	Tax         *Tax      `json:"tax,omitempty"`
	Discount    *Discount `json:"discount,omitempty"`
	// contains filtered or unexported fields
}

Item represent a 'product' or a 'service'

func (*Item) Prepare

func (i *Item) Prepare() error

Prepare convert strings to decimal

func (*Item) TaxWithTotalDiscounted

func (i *Item) TaxWithTotalDiscounted() decimal.Decimal

TaxWithTotalDiscounted returns the tax with total discounted

func (*Item) TotalWithTaxAndDiscount

func (i *Item) TotalWithTaxAndDiscount() decimal.Decimal

TotalWithTaxAndDiscount returns the total with tax and discount

func (*Item) TotalWithoutTaxAndWithDiscount

func (i *Item) TotalWithoutTaxAndWithDiscount() decimal.Decimal

TotalWithoutTaxAndWithDiscount returns the total without tax and with discount

func (*Item) TotalWithoutTaxAndWithoutDiscount

func (i *Item) TotalWithoutTaxAndWithoutDiscount() decimal.Decimal

TotalWithoutTaxAndWithoutDiscount returns the total without tax and without discount

type MultiDocument

type MultiDocument struct {
	Options *Options
	Header  *HeaderFooter
	Footer  *HeaderFooter
	Docs    []*Document
	// contains filtered or unexported fields
}

MultiDocument represents a collection of documents to be generated in a single PDF

func NewMultiDocument

func NewMultiDocument(options *Options) *MultiDocument

NewMultiDocument creates a new multi-document generator

func (*MultiDocument) AddDocument

func (md *MultiDocument) AddDocument(doc *Document)

AddDocument adds a document to the multi-document collection

func (*MultiDocument) Build

func (md *MultiDocument) Build() (*fpdf.Fpdf, error)

Build generates the PDF with all documents

func (*MultiDocument) GetPdf

func (md *MultiDocument) GetPdf() *fpdf.Fpdf

func (*MultiDocument) SetFooter

func (md *MultiDocument) SetFooter(footer *HeaderFooter)

SetFooter sets the footer for all documents

func (*MultiDocument) SetHeader

func (md *MultiDocument) SetHeader(header *HeaderFooter)

SetHeader sets the header for all documents

type Options

type Options struct {
	AutoPrint bool `json:"auto_print,omitempty"`
	// IsTaxDisplay controls whether tax-related values are displayed in totals.
	IsTaxDisplay bool `default:"true" json:"is_tax_display,omitempty"`

	CurrencySymbol       string `default:"€ " json:"currency_symbol,omitempty"`
	CurrencyPrecision    int    `default:"0" json:"currency_precision,omitempty"`
	CurrencyDecimal      string `default:"." json:"currency_decimal,omitempty"`
	CurrencyThousand     string `default:" " json:"currency_thousand,omitempty"`
	Format               string `default:"%s %v" json:"format,omitempty"`
	FormatNegative       string `default:"%s -%v" json:"format_negative,omitempty"`
	FormatZero           string `default:"%s 0" json:"format_zero,omitempty"`
	BarCode              string `default:"" json:"barcode,omitempty"`
	TextTypeInvoice      string `default:"INVOICE" json:"text_type_invoice,omitempty"`
	TextTypeQuotation    string `default:"QUOTATION" json:"text_type_quotation,omitempty"`
	TextTypeDeliveryNote string `default:"DELIVERY NOTE" json:"text_type_delivery_note,omitempty"`
	TextPhoneTitle       string `json:"text_phone_title,omitempty" default:"Phone"`

	TextRefTitle         string `default:"Ref." json:"text_ref_title,omitempty"`
	TextVersionTitle     string `default:"Version" json:"text_version_title,omitempty"`
	TextDateTitle        string `default:"Date" json:"text_date_title,omitempty"`
	TextPaymentTermTitle string `default:"Payment term" json:"text_payment_term_title,omitempty"`

	TextItemsNameTitle     string `default:"Name" json:"text_items_name_title,omitempty"`
	TextItemsUnitCostTitle string `default:"Unit price" json:"text_items_unit_cost_title,omitempty"`
	TextItemsQuantityTitle string `default:"Qty" json:"text_items_quantity_title,omitempty"`
	TextItemsTotalHTTitle  string `default:"Total no tax" json:"text_items_total_ht_title,omitempty"`
	TextItemsTaxTitle      string `default:"Tax" json:"text_items_tax_title,omitempty"`
	TextItemsDiscountTitle string `default:"Discount" json:"text_items_discount_title,omitempty"`
	TextItemsTotalTTCTitle string `default:"Total" json:"text_items_total_ttc_title,omitempty"`

	TextTotalTotal       string `default:"TOTAL" json:"text_total_total,omitempty"`
	TextTotalDiscounted  string `default:"TOTAL DISCOUNTED" json:"text_total_discounted,omitempty"`
	TextTotalShippingFee string `default:"SHIPPING FEE" json:"text_total_shipping_fee,omitempty"`
	TextTotalTax         string `default:"TAX" json:"text_total_tax,omitempty"`
	TextTotalWithTax     string `default:"TOTAL WITH TAX" json:"text_total_with_tax,omitempty"`
	TextInvoiceTitle     string `default:"INVOICE" json:"text_invoice_title,omitempty"`

	BaseTextColor []int `default:"[35,35,35]" json:"base_text_color,omitempty"`
	GreyTextColor []int `default:"[82,82,82]" json:"grey_text_color,omitempty"`
	GreyBgColor   []int `default:"[232,232,232]" json:"grey_bg_color,omitempty"`
	DarkBgColor   []int `default:"[212,212,212]" json:"dark_bg_color,omitempty"`

	Font     string `default:"Helvetica"`
	BoldFont string `default:"Helvetica"`

	UnicodeTranslateFunc UnicodeTranslateFunc
}

Options for Document

type Tax

type Tax struct {
	Percent string `json:"percent,omitempty"` // Tax in percent ex 17
	Amount  string `json:"amount,omitempty"`  // Tax in amount ex 123.40
	// contains filtered or unexported fields
}

Tax define tax as percent or fixed amount

func (*Tax) Prepare

func (t *Tax) Prepare() error

Prepare convert strings to decimal

type UnicodeTranslateFunc

type UnicodeTranslateFunc func(string) string

UnicodeTranslateFunc ...

Directories

Path Synopsis
examples
barcode command
bytes command
iso_8859_2_cp command
multi_document command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL