diff --git a/cmd/config.go b/cmd/config.go
index 00e6d92..d50fb36 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -8,9 +8,12 @@ import (
type Config struct {
TemplatesPath string `env:"TEMPLATES_PATH" envDefault:"cmd/testdata/"`
- RenderTimeout time.Duration `env:"RENDER_TIMEOUT envDefault:"3s"`
+ RenderTimeout time.Duration `env:"RENDER_TIMEOUT" envDefault:"10s"`
ServerHost string `env:"SERVER_HOST" envDefault:"localhost"`
ServerPort int `env:"SERVER_PORT" envDefault:"8080"`
+
+ ViewportHeight int `env:"VIEWPORT_HEIGHT" envDefault:"2048"`
+ ViewportWidth int `env:"VIEWPORT_WIDTH" envDefault:"1920"`
}
func (config Config) BaseUrl() string {
diff --git a/cmd/module.go b/cmd/module.go
index 9c1989b..8d84224 100644
--- a/cmd/module.go
+++ b/cmd/module.go
@@ -22,7 +22,7 @@ type Module struct {
func NewModule(config Config) *Module {
engine := data.NewGolangTemplateEngine()
repo := data.NewFilesystemTemplateRepo(config.TemplatesPath)
- png := data.NewPngReportExporter(config.RenderTimeout)
+ png := data.NewPngReportExporter(config.RenderTimeout, config.ViewportHeight, config.ViewportWidth)
pdf := data.NewPdfReportExporter(png)
tmplSrv := business.NewTemplateService(engine, repo)
diff --git a/examples/long_invoice.html b/examples/long_invoice.html
new file mode 100644
index 0000000..ede9b3c
--- /dev/null
+++ b/examples/long_invoice.html
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
+
COMMERCIAL INVOICE
+ This invoice must be completed in English.
+
+
+
+
EXPORTER:
+
TAX ID#:
+
Contact Name:
+
Telephone No.:
+
E-Mail:
+
Company Name/Address:
+
Country/Territory:
+
Parties to transaction:
+
+ Related
+ Non-Related
+
+
+
+
Ship Date:
+
Air Waybill No./Tracking No.:
+
+
+ Invoice No.:
+ Purchase Order No.:
+
+
+ Payment Terms:
+ Bill of Lading:
+
+
+
Purpose of Shipment:
+
+
+
+
+
+ CONSIGNEE:
+ TAX ID#:
+ Contact Name:
+ Telephone No.:
+ E-Mail:
+ Company Name/Address:
+ Country/Territory:
+
+
+ SOLD TO/IMPORTER (if different from Consignee):
+ Same as CONSIGNEE:
+ TAX ID#:
+ Company Name/Address:
+ Country/Territory:
+
+
+
+
+
+ If there is a designated broker for this shipment, please provide contact information.
+
+
+ Name of broker:
+ Tel. No.:
+ Contact Name:
+
+
+
+
+
+ Duties and Taxes Payable by
+ Exporter
+ Consignee
+ Other
+ If other please specify:
+
+
+
+
+
+
+
+ No. of Packages |
+ No. of Units |
+ Net Weight (LBS/KGS) |
+ Unit of Measure |
+ Description of Goods |
+ Harmonized Tariff Number |
+ Country of Manufacture |
+ Unit Value |
+ Total Value |
+
+
+
+
+
+ {{- range $i, $j := .Sequence 20 }}
+ {{- if lt $i (len $.Values.lineItems) }}
+ {{- with index $.Values.lineItems $i }}
+
+ {{ .quantity }} |
+ {{ .quantity }} |
+ {{ .netWeight }} |
+ EA |
+ {{ .description }} |
+ |
+ {{ .origin }} |
+ {{ .unitValue }} |
+ {{ .totalValue }} |
+
+ {{- end }}
+ {{- else }}
+
+ 0 |
+ 0 |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+ {{- end }}
+ {{- end }}
+
+
+
+
+
+
+
+
+
+
+
+ Total Pkgs |
+ No. of Units |
+ Total Net Weight |
+ Total Gross Weight |
+ Terms of Sale |
+
+
+
+
+
+ {{ .Values.totalPackages }} |
+ {{ .Values.totalUnits }} |
+ {{ .Values.totalNetWeight }} KG |
+ {{ .Values.totalGrossWeight }} KG |
+ DDP |
+
+
+
+
+
+
+ Special Instructions:
+
+
+
+ Declaration Statement(s):
+
+
+
+ I declare that all the information contained in this invoice to be true and correct.
+
+
+
+ Originator or Name of Company Representative if the invoice is being completed on behalf of a company or individual:
+
+
+
+
+
+
+
+ Subtotal: |
+ {{ .Values.subTotal }} |
+
+
+ Insurance: |
+ 0.00 |
+
+
+ Freight: |
+ {{ .Values.freight }} |
+
+
+ Packing: |
+ 0.00 |
+
+
+ Handling: |
+ 0.00 |
+
+
+ Other: |
+ 0.00 |
+
+
+ Invoice Total: |
+ {{ .Values.total }} |
+
+
+ Country Code: |
+ {{ .Values.countryCode }} |
+
+
+
+
+
+
+
+
+ Signature/Title/Date:
+
+
+
+
+
+
\ No newline at end of file
diff --git a/internal/data/png_report_exporter.go b/internal/data/png_report_exporter.go
index 2e935dc..ad36d4f 100644
--- a/internal/data/png_report_exporter.go
+++ b/internal/data/png_report_exporter.go
@@ -10,17 +10,17 @@ import (
)
type pngReportExporter struct {
- timeout time.Duration
+ timeout time.Duration
+ viewportHeight int
+ viewportWidth int
}
-func NewPngReportExporter(timeout time.Duration) *pngReportExporter {
- return &pngReportExporter{timeout: timeout}
+func NewPngReportExporter(timeout time.Duration, vpHeight, vpWidth int) *pngReportExporter {
+ return &pngReportExporter{timeout: timeout, viewportHeight: vpHeight, viewportWidth: vpWidth}
}
func (pre *pngReportExporter) Export(url string) ([]byte, *models.PrintOptions, error) {
- baseCtx, to := context.WithTimeout(context.Background(), pre.timeout)
- ctx, cancel := chromedp.NewContext(baseCtx)
- defer to()
+ ctx, cancel := createContext(pre.timeout, pre.viewportHeight, pre.viewportWidth)
defer cancel()
var res []byte
@@ -39,6 +39,28 @@ func (pre *pngReportExporter) Export(url string) ([]byte, *models.PrintOptions,
return res, &options, nil
}
+func createContext(timeout time.Duration, vph int, vpw int) (context.Context, context.CancelFunc) {
+ baseCtx, cancelTimeout := context.WithTimeout(context.Background(), timeout)
+
+ opts := []chromedp.ExecAllocatorOption{
+ chromedp.WindowSize(vpw, vph),
+ chromedp.NoFirstRun,
+ chromedp.NoDefaultBrowserCheck,
+ chromedp.Headless,
+ chromedp.DisableGPU,
+ }
+ allocCtx, cancelAlloc := chromedp.NewExecAllocator(baseCtx, opts...)
+ ctx, cancelCtx := chromedp.NewContext(allocCtx)
+
+ cancelFuncs := func() {
+ cancelTimeout()
+ cancelAlloc()
+ cancelCtx()
+ }
+
+ return ctx, cancelFuncs
+}
+
const extractPrintOptions = `function extractStyles() {
var styles = getComputedStyle(document.body);
diff --git a/internal/data/report_exporter_test.go b/internal/data/report_exporter_test.go
index 0939f10..e992bad 100644
--- a/internal/data/report_exporter_test.go
+++ b/internal/data/report_exporter_test.go
@@ -12,7 +12,7 @@ import (
)
func TestPngReportExporter_Export_PrintableNotFound(t *testing.T) {
- ts := NewPngReportExporter(1 * time.Second)
+ ts := NewPngReportExporter(1*time.Second, 2000, 1920)
png, _, err := ts.Export(fmt.Sprintf("http://localhost:%d/subfolder/report2.html", testPort))
assert.NotNil(t, err)
assert.Nil(t, png)
@@ -20,7 +20,7 @@ func TestPngReportExporter_Export_PrintableNotFound(t *testing.T) {
}
func TestPngReportExporter_Export_PrintableFound(t *testing.T) {
- ts := NewPngReportExporter(2 * time.Second)
+ ts := NewPngReportExporter(2*time.Second, 2000, 1920)
png, _, err := ts.Export(fmt.Sprintf("http://localhost:%d/report1.html", testPort))
assert.Nil(t, err)
assert.NotEmpty(t, png)
@@ -30,7 +30,7 @@ func TestPngReportExporter_Export_PrintableFound(t *testing.T) {
}
func TestPdfReportExporter_Export_PrintableNotFound(t *testing.T) {
- ts := NewPdfReportExporter(NewPngReportExporter(1 * time.Second))
+ ts := NewPdfReportExporter(NewPngReportExporter(1*time.Second, 2000, 1920))
png, _, err := ts.Export(fmt.Sprintf("http://localhost:%d/subfolder/report2.html", testPort))
assert.NotNil(t, err)
assert.Nil(t, png)
@@ -38,7 +38,7 @@ func TestPdfReportExporter_Export_PrintableNotFound(t *testing.T) {
}
func TestPdfReportExporter_Export_PrintableFound(t *testing.T) {
- ts := NewPdfReportExporter(NewPngReportExporter(1 * time.Second))
+ ts := NewPdfReportExporter(NewPngReportExporter(1*time.Second, 2000, 1920))
pdf, _, err := ts.Export(fmt.Sprintf("http://localhost:%d/report1.html", testPort))
assert.Nil(t, err)
assert.NotEmpty(t, pdf)
diff --git a/internal/data/testdata/report1.png b/internal/data/testdata/report1.png
index 49488e0..647ccb0 100755
Binary files a/internal/data/testdata/report1.png and b/internal/data/testdata/report1.png differ