diff --git a/README.md b/README.md index 397e05ad..fbb7296d 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ go get -u github.com/johnfercher/maroto * [SetBorder](https://pkg.go.dev/github.com/johnfercher/maroto/pkg/pdf?tab=doc#PdfMaroto.SetBorder): Used to draw rectangles in every row and column * [SetBackgroundColor](https://pkg.go.dev/github.com/johnfercher/maroto/pkg/pdf?tab=doc#PdfMaroto.SetBackgroundColor): Used to change the background color of one cell. * [SetPageMargins](https://pkg.go.dev/github.com/johnfercher/maroto/pkg/pdf?tab=doc#PdfMaroto.SetPageMargins): Customize the page margins +* NewMarotoCustomSize(): Create Maroto with custom page dimensions * Automatic New Page: New pages are generated automatically when needed. * 100% Unicode * Save: You can [save on disk](https://pkg.go.dev/github.com/johnfercher/maroto/pkg/pdf?tab=doc#PdfMaroto.OutputFileAndClose) or export to a [base64 string](https://pkg.go.dev/github.com/johnfercher/maroto/pkg/pdf?tab=doc#PdfMaroto.Output) @@ -246,4 +247,4 @@ func main() { ## Stargazers over time -[![Stargazers over time](https://starchart.cc/johnfercher/maroto.svg)](https://starchart.cc/johnfercher/maroto) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/johnfercher/maroto.svg)](https://starchart.cc/johnfercher/maroto) diff --git a/internal/examples/customsize/main.go b/internal/examples/customsize/main.go new file mode 100644 index 00000000..a16bfc10 --- /dev/null +++ b/internal/examples/customsize/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "github.com/johnfercher/maroto/pkg/consts" + "github.com/johnfercher/maroto/pkg/pdf" + "github.com/johnfercher/maroto/pkg/props" + "os" + "time" +) + +func main() { + begin := time.Now() + m := pdf.NewMarotoCustomSize(consts.Landscape, "C6", "mm", 114.0, 162.0) + m.SetPageMargins(5, 5, 5) + // m.SetBorder(true) + + m.Row(40, func() { + m.Col(4, func() { + _ = m.FileImage("internal/assets/images/biplane.jpg", props.Rect{ + Center: true, + Percent: 50, + }) + }) + m.Col(4, func() { + m.Text("Gopher International Shipping, Inc.", props.Text{ + Top: 12, + Size: 12, + Extrapolate: true, + }) + }) + m.ColSpace(4) + }) + + m.Line(10) + + m.Row(30, func() { + m.Col(12, func() { + m.Text("João Sant'Ana 100 Main Street", props.Text{ + Size: 10, + Align: consts.Right, + }) + m.Text("Springfield TN 39021", props.Text{ + Size: 10, + Align: consts.Right, + Top: 10, + }) + m.Text("United States (USA)", props.Text{ + Size: 10, + Align: consts.Right, + Top: 20, + }) + }) + }) + + err := m.OutputFileAndClose("internal/examples/pdfs/customsize.pdf") + if err != nil { + fmt.Println("Could not save PDF:", err) + os.Exit(1) + } + + end := time.Now() + fmt.Println(end.Sub(begin)) +} diff --git a/internal/examples/pdfs/customsize.pdf b/internal/examples/pdfs/customsize.pdf new file mode 100644 index 00000000..4e58fb9e Binary files /dev/null and b/internal/examples/pdfs/customsize.pdf differ diff --git a/pkg/pdf/example_test.go b/pkg/pdf/example_test.go index ebbc0925..93d16cb5 100644 --- a/pkg/pdf/example_test.go +++ b/pkg/pdf/example_test.go @@ -20,6 +20,16 @@ func ExampleNewMaroto() { // Do more things and save... } +// ExampleNewMaroto demonstrates how to create maroto with custom page size +func ExampleNewMarotoCustomSize() { + m := pdf.NewMarotoCustomSize(consts.Landscape, "C6", "mm", 114.0, 162.0) + + // Do things + m.GetPageMargins() + + // Do more things and save... +} + // ExamplePdfMaroto_AddPage how to force add a new page func ExamplePdfMaroto_AddPage() { m := pdf.NewMaroto(consts.Portrait, consts.A4) diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 1cf0ee78..320d231d 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -76,10 +76,22 @@ type PdfMaroto struct { pageSize consts.PageSize } -// NewMaroto create a Maroto instance returning a pointer to PdfMaroto +// NewMarotoCustomSize creates a Maroto instance returning a pointer to PdfMaroto // Receive an Orientation and a PageSize. -func NewMaroto(orientation consts.Orientation, pageSize consts.PageSize) Maroto { - fpdf := gofpdf.New(string(orientation), "mm", string(pageSize), "") +// Use if custom page size is needed. Otherwise use NewMaroto() shorthand if using page sizes from consts.Pagesize. +// If using custom width and height, pageSize is just a string value for the format and takes no effect. +// Width and height inputs are measurements of the page in Portrait orientation. +func NewMarotoCustomSize(orientation consts.Orientation, pageSize consts.PageSize, unitStr string, width, height float64) Maroto { + fpdf := gofpdf.NewCustom(&gofpdf.InitType{ + OrientationStr: string(orientation), + UnitStr: unitStr, + SizeStr: string(pageSize), + Size: gofpdf.SizeType{ + Wd: width, + Ht: height, + }, + FontDirStr: "", + }) fpdf.SetMargins(10, 10, 10) math := internal.NewMath(fpdf) @@ -121,6 +133,13 @@ func NewMaroto(orientation consts.Orientation, pageSize consts.PageSize) Maroto return maroto } +// NewMaroto create a Maroto instance returning a pointer to PdfMaroto +// Receive an Orientation and a PageSize. +// Shorthand when using a preset page size from consts.PageSize +func NewMaroto(orientation consts.Orientation, pageSize consts.PageSize) Maroto { + return NewMarotoCustomSize(orientation, pageSize, "mm", 0, 0) +} + // AddPage adds a new page in the PDF func (s *PdfMaroto) AddPage() { _, pageHeight := s.Pdf.GetPageSize() diff --git a/pkg/pdf/pdf_test.go b/pkg/pdf/pdf_test.go index 0b8bf3b5..99ad9cec 100644 --- a/pkg/pdf/pdf_test.go +++ b/pkg/pdf/pdf_test.go @@ -155,6 +155,88 @@ func TestNewPdf(t *testing.T) { } +func TestNewCustomSizePdf(t *testing.T) { + cases := []struct { + name string + orientation consts.Orientation + pageSize consts.PageSize + unit string + height float64 + width float64 + assert func(t *testing.T, m pdf.Maroto) + }{ + { + "When portrait and C6", + consts.Portrait, + "C6", + "mm", + 162.0, + 114.0, + func(t *testing.T, m pdf.Maroto) { + assert.NotNil(t, m) + assert.Equal(t, fmt.Sprintf("%T", m), "*pdf.PdfMaroto") + width, height := m.GetPageSize() + assert.InDelta(t, width, 114.0, 0.1) + assert.InDelta(t, height, 162.0, 0.1) + }, + }, + { + "When landscape and C6", + consts.Landscape, + "C6", + "mm", + 162.0, + 114.0, + func(t *testing.T, m pdf.Maroto) { + assert.NotNil(t, m) + assert.Equal(t, fmt.Sprintf("%T", m), "*pdf.PdfMaroto") + width, height := m.GetPageSize() + assert.InDelta(t, width, 162.0, 0.1) + assert.InDelta(t, height, 114.0, 0.1) + }, + }, + { + "When portrait and B3 and given in cm", + consts.Portrait, + "B3", + "cm", + 50.0, + 35.3, + func(t *testing.T, m pdf.Maroto) { + assert.NotNil(t, m) + assert.Equal(t, fmt.Sprintf("%T", m), "*pdf.PdfMaroto") + width, height := m.GetPageSize() + assert.InDelta(t, width, 35.3, 0.1) + assert.InDelta(t, height, 50.0, 0.1) + }, + }, + { + "When landdscape and B3 and given in cm", + consts.Landscape, + "B3", + "cm", + 50.0, + 35.3, + func(t *testing.T, m pdf.Maroto) { + assert.NotNil(t, m) + assert.Equal(t, fmt.Sprintf("%T", m), "*pdf.PdfMaroto") + width, height := m.GetPageSize() + assert.InDelta(t, width, 50.0, 0.1) + assert.InDelta(t, height, 35.3, 0.1) + }, + }, + } + + for _, c := range cases { + // Act + m := pdf.NewMarotoCustomSize(c.orientation, c.pageSize, c.unit, c.width, c.height) + + // Assert + c.assert(t, m) + } + +} + func TestPdfMaroto_SetGetDebugMode(t *testing.T) { // Arrange m := pdf.NewMaroto(consts.Portrait, consts.A4)