package main import ( "fmt" "io/ioutil" "log" "os" "os/exec" "path/filepath" "github.com/jung-kurt/gofpdf" "gopkg.in/yaml.v2" ) // Metadata type type Metadata struct { InvoiceNr string InvoiceInfo string InvoiceDdate string Vat float64 Account string DueDate string } // Address type type Address struct { Name string Street string Zip string City string TelNo string Email string } // InvoiceItem type type InvoiceItem struct { Text string Quantity float64 PicePerUnit float64 } // InvoiceData type type InvoiceData struct { Metadata Metadata SenderAddress Address BillingAddress Address Item []InvoiceItem } /* global variable declaration */ var pdf *gofpdf.Fpdf var yPos float64 var invoiceData InvoiceData var progDir string const marginTop = 7 const logoTop = 6 const logoHeight = 20 const lineSpacing = 5 const addressTop = 50 const line1Top = 100 const tabstopLeft = 20 const tabstopLeftAlt = 32 const tabstopAddress = 120 const tabstopCount = 10 const tabstopPrice = 10 const tabstopTotal = 170 const tabstopLogo = 155 const tabstopRight = 200 func readInvoiceData(filename string) { data, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } //fmt.Printf("File contents: %s", data) err = yaml.Unmarshal([]byte(data), &invoiceData) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", invoiceData) fmt.Printf("%s\n", invoiceData.BillingAddress.Name) } func writeText(x float64, y float64, text string, alignStr ...string) { tr := pdf.UnicodeTranslatorFromDescriptor("") align := "LT" if len(alignStr) > 0 { align = alignStr[0] } pdf.SetXY(x, y) pdf.CellFormat(0, 11, tr(text), "", 0, align, false, 0, "") } func setupInvoice() { pdf = gofpdf.New("P", "mm", "A4", "") pdf.SetMargins(0, 0, 0) pdf.SetFontLocation("fonts") pdf.AddFont("Dejavusans", "", "DejaVuSans.json") pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json") pdf.SetFont("Dejavusans", "", 10) } func printPageHeader(firstPage bool) { var opt gofpdf.ImageOptions pdf.AddPage() yPos = marginTop pdf.SetFont("Dejavusans-Bold", "", 10) writeText(tabstopLeft, yPos, "nbit Informatik GmbH") pdf.SetFont("Dejavusans", "", 10) yPos = yPos + lineSpacing writeText(tabstopLeft, yPos, "Kirchweg 2") yPos = yPos + lineSpacing writeText(tabstopLeft, yPos, "3510 Konolfingen") yPos = yPos + lineSpacing yPos = yPos + lineSpacing writeText(tabstopLeft, yPos, "Tel.") writeText(tabstopLeftAlt, yPos, "+41 31 792 00 40") yPos = yPos + lineSpacing writeText(tabstopLeft, yPos, "EMail") writeText(tabstopLeftAlt, yPos, "joerg.lehmann@nbit.ch") yPos = yPos + lineSpacing opt.ImageType = "png" opt.ReadDpi = true pdf.ImageOptions("logos/nbit-logo.png", tabstopLogo, logoTop, 0, logoHeight, false, opt, 0, "") } func printAddress() { fmt.Printf("Blabla: %s\n", invoiceData.BillingAddress.Name) yPos = addressTop writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Name) yPos = yPos + lineSpacing writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Street) yPos = yPos + lineSpacing writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City) yPos = yPos + lineSpacing pdf.Line(tabstopLeft, line1Top, tabstopRight, line1Top) } func printQR() { var opt gofpdf.ImageOptions cmd := exec.Command(filepath.Join(progDir, "qrbill.sh"), "--account", invoiceData.Metadata.Account, "--amount", "123.00", "--creditor-name", invoiceData.SenderAddress.Name, "--creditor-street", invoiceData.SenderAddress.Street, "--creditor-postalcode", invoiceData.SenderAddress.Zip, "--creditor-city", invoiceData.SenderAddress.City, "--extra-infos", invoiceData.Metadata.InvoiceInfo, "--debtor-name", invoiceData.BillingAddress.Name, "--debtor-street", invoiceData.BillingAddress.Street, "--debtor-postalcode", invoiceData.BillingAddress.Zip, "--debtor-city", invoiceData.BillingAddress.City, "--due-date", invoiceData.Metadata.DueDate, "--language", "de") cmd.Env = append(os.Environ(), "INVNO="+invoiceData.Metadata.InvoiceNr, ) stdoutStderr, err := cmd.CombinedOutput() fmt.Printf("%s\n", stdoutStderr) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", stdoutStderr) opt.ImageType = "jpeg" opt.ReadDpi = true pdf.ImageOptions("qr-images/"+invoiceData.Metadata.InvoiceNr+".jpg", 0, 200, 0, 0, false, opt, 0, "") } func main() { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Fatal(err) } progDir = dir if len(os.Args) != 2 { fmt.Printf("usage: mkinvoice \n") os.Exit(1) } readInvoiceData(os.Args[1]) setupInvoice() printPageHeader(true) printAddress() printQR() err = pdf.OutputFileAndClose(filepath.Join(progDir, "output", invoiceData.Metadata.InvoiceNr+".pdf")) if err == nil { fmt.Printf("Successfully created invoice\n") } else { fmt.Printf("Error: %v\n", err) } }