Skip to content

Commit

Permalink
[UP-424] Warehouse shipment report template example (#224)
Browse files Browse the repository at this point in the history
* initial implementation

* update template

* update screenshot

* fix import

* update readme

* update dependecies

* update unipdf version

* fix comment and remove unused function
  • Loading branch information
3ace authored May 24, 2023
1 parent 75df410 commit 76e6895
Show file tree
Hide file tree
Showing 11 changed files with 614 additions and 8 deletions.
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ require (
github.com/unidoc/globalsign-dss v0.0.0-20220330092912-b69d85b63736
github.com/unidoc/pkcs7 v0.1.1-0.20220329190817-dd59b9eba14c
github.com/unidoc/unichart v0.1.0
github.com/unidoc/unipdf/v3 v3.44.0
github.com/unidoc/unipdf/v3 v3.45.0
github.com/wcharczuk/go-chart/v2 v2.1.0
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
golang.org/x/text v0.4.0
golang.org/x/image v0.5.0
golang.org/x/text v0.7.0
google.golang.org/api v0.102.0
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e
google.golang.org/protobuf v1.28.1
Expand Down
17 changes: 11 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,8 @@ github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a h1:RLtvUhe4DsUDl6
github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a/go.mod h1:j+qMWZVpZFTvDey3zxUkSgPJZEX33tDgU/QIA0IzCUw=
github.com/unidoc/unichart v0.1.0 h1:GoJ/rxSoOYZsqlG3yOJpKkwgfsIQgb9hHX7bILZHcCg=
github.com/unidoc/unichart v0.1.0/go.mod h1:9sJXeqxIIsU2D07tmhpDMoND0mBFRGfKBJnXZMsJnzk=
github.com/unidoc/unipdf/v3 v3.44.0 h1:qPE4blVdQL9YymICEyPLK88DMUFJbWIiZ0uhk+jk9/Y=
github.com/unidoc/unipdf/v3 v3.44.0/go.mod h1:3RPr6hXP+PNjuoACxvqv1UujSTjoapl4iuiobt/Lccw=
github.com/unidoc/unipdf/v3 v3.45.0 h1:ao7sWfB04ZLvWit5SSem0N/01pZxStoVxorH8nhCnJk=
github.com/unidoc/unipdf/v3 v3.45.0/go.mod h1:g42g9gaGCT2hLoNK+r/RZdNVnvhF1X6qx6wpTKJwg2E=
github.com/unidoc/unitype v0.2.1 h1:x0jMn7pB/tNrjEVjy3Ukpxo++HOBQaTCXcTYFA6BH3w=
github.com/unidoc/unitype v0.2.1/go.mod h1:mafyug7zYmDOusqa7G0dJV45qp4b6TDAN+pHN7ZUIBU=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
Expand Down Expand Up @@ -447,8 +447,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down Expand Up @@ -519,8 +520,9 @@ golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -625,10 +627,12 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -638,8 +642,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
1 change: 1 addition & 0 deletions templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ Documentation PDF file: [unipdf-templates-documentation.pdf](documentation/unipd
- [Sample Medication Schedule Document](medication-schedule-report): showcases the usage of creator templates by creating a sample medication schedule document.
- [Sample log book document](log-book-report): showcases the usage of creator templates by creating a sample
log book document.
- [Sample Warehouse Shipment Report](warehouse-shipment-report): showcases the usage of creator templates by creating a sample warehouse shipment report.
8 changes: 8 additions & 0 deletions templates/warehouse-shipment-report/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Sample warehouse shipment report
================================

This example showcases the usage of creator templates by creating a sample warehouse shipment report.

<p>
<img src="templates/res/screenshot.png" alt="sample-warehouse-shipment-report-preview" width="100%" />
</p>
195 changes: 195 additions & 0 deletions templates/warehouse-shipment-report/pdf_warehouse_shipment_report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* This example showcases the usage of creator templates by creating a sample
* warehouse shipment report.
*
* Run as: go run pdf_warehouse_shipment_report.go
*/

package main

import (
"bytes"
"encoding/json"
"image"
"image/color"
"io"
"log"
"os"
"text/template"

"github.com/boombuler/barcode/code128"
"github.com/unidoc/unipdf/v3/common"
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/creator"
"github.com/unidoc/unipdf/v3/model"
"golang.org/x/image/draw"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
)

func init() {
// Make sure to load your metered License API key prior to using the library.
// If you need a key, you can sign up and create a free one at https://cloud.unidoc.io.
err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`))
if err != nil {
panic(err)
}

common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug))
}

func main() {
c := creator.New()
c.SetPageMargins(25, 25, 150, 25)

// Read main content template.
mainTpl, err := readTemplate("templates/main.tpl")
if err != nil {
log.Fatal(err)
}

// Read shipment report JSON data.
report, err := readReportData("shipment_report.json")
if err != nil {
log.Fatal(err)
}

// Draw main content template.
imageMap := map[string]*model.Image{}
tplOpts := &creator.TemplateOptions{
ImageMap: imageMap,
HelperFuncMap: template.FuncMap{
"add": func(a, b int) int {
return a + b
},
"createBarcode": func(text string) (string, error) {
barcode, err := code128.Encode(text)
if err != nil {
return "", err
}

tmpImg := image.NewRGBA(image.Rect(0, 0, 100, 30))

draw.NearestNeighbor.Scale(tmpImg, image.Rect(0, 0, 100, 20), image.Image(barcode), barcode.Bounds(), draw.Over, nil)

col := color.RGBA{0, 0, 0, 255}
point := fixed.Point26_6{X: fixed.I(10), Y: fixed.I(30)}

d := &font.Drawer{
Dst: tmpImg,
Src: image.NewUniform(col),
Face: basicfont.Face7x13,
Dot: point,
}
d.DrawString(text)

img, err := model.ImageHandling.NewImageFromGoImage(tmpImg)
if err != nil {
return "", err
}

imageMap[text] = img

return text, nil
},
},
}

if err := c.DrawTemplate(mainTpl, report.Shipments, tplOpts); err != nil {
log.Fatal(err)
}

// Draw header.
drawHeader := func(tplPath string, block *creator.Block, company *Company) {
// Read template.
tpl, err := readTemplate(tplPath)
if err != nil {
log.Fatal(err)
}

// Draw template.
if err := block.DrawTemplate(c, tpl, company, tplOpts); err != nil {
log.Fatal(err)
}
}

c.DrawHeader(func(block *creator.Block, args creator.HeaderFunctionArgs) {
drawHeader("templates/header.tpl", block, report.Company)
})

// Write output file.
if err := c.WriteToFile("unipdf-warehouse-shipment-report.pdf"); err != nil {
log.Fatal(err)
}
}

// readTemplate reads the template at the specified file path and returns it
// as an io.Reader.
func readTemplate(tplFile string) (io.Reader, error) {
file, err := os.Open(tplFile)
if err != nil {
return nil, err
}
defer file.Close()

buf := bytes.NewBuffer(nil)
if _, err = io.Copy(buf, file); err != nil {
return nil, err
}

return buf, nil
}

// readReportData reads the shipment report data from a specified JSON file.
func readReportData(jsonFile string) (*Report, error) {
file, err := os.Open(jsonFile)
if err != nil {
return nil, err
}
defer file.Close()

report := &Report{}
if err := json.NewDecoder(file).Decode(report); err != nil {
return nil, err
}

return report, nil
}

// Report represents the report data.
type Report struct {
Company *Company `json:"company"`
Shipments []*Shipment `json:"shipments"`
}

// Company represents company data.
type Company struct {
Brand string `json:"brand"`
Name string `json:"name"`
POBox string `json:"pobox"`
Address string `json:"address"`
Area string `json:"area"`
City string `json:"city"`
Country string `json:"country"`
}

// Shipment represent the shipment data.
type Shipment struct {
Time string `json:"time"`
Orders []*Order `json:"orders"`
}

// Order represents the order data.
type Order struct {
Time string `json:"time"`
PIC string `json:"pic"`
Products []*Product `json:"products"`
}

// Product represent the product data.
type Product struct {
Barcode string `json:"barcode"`
Code string `json:"code"`
Name string `json:"name"`
}
Loading

0 comments on commit 76e6895

Please sign in to comment.