Simple

Before you begin

You should get your API key from your UniCloud account.

If this is your first time using UniPDF SDK, follow this guide to set up a local development environment.

Project setup

Clone the project repository

In your terminal, clone the examples repository. It contains the Go code we will be using for this guide.

git clone https://github.com/unidoc/unipdf-examples.git

Navigate to the tables folder in the unipdf-examples directory.

cd unipdf-examples/tables

Configure environment variables

Replace the UNIDOC_LICENSE_API_KEY with API credentials from your UniCloud account.

Linux/Mac

export UNIDOC_LICENSE_API_KEY=PUT_YOUR_API_KEY_HERE

Windows

set UNIDOC_LICENSE_API_KEY=PUT_YOUR_API_KEY_HERE

How it works

/*
* This example showcases PDF tables features using unipdf's creator package.
* The output is saved as unipdf-simple-tables.pdf which illustrates how to
* create a basic table.
*/
package main
import (
"fmt"
"log"
"os"
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/creator"
"github.com/unidoc/unipdf/v3/model"
)
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)
}
}
func main() {
c := creator.New()
c.SetPageMargins(50, 50, 50, 50)
// Create report fonts.
// UniPDF supports a number of font-families, which can be accessed using model.
font, err := model.NewStandard14Font(model.HelveticaName)
if err != nil {
log.Fatal(err)
}
fontBold, err := model.NewStandard14Font(model.HelveticaBoldName)
if err != nil {
log.Fatal(err)
}
// Generate basic usage chapter.
if err := basicUsage(c, font, fontBold); err != nil {
log.Fatal(err)
}
// Write to output file.
if err := c.WriteToFile("unipdf-simple-tables.pdf"); err != nil {
log.Fatal(err)
}
}
func basicUsage(c *creator.Creator, font, fontBold *model.PdfFont) error {
// Create chapter.
ch := c.NewChapter("Basic usage")
ch.SetMargins(0, 0, 50, 0)
ch.GetHeading().SetFont(font)
ch.GetHeading().SetFontSize(18)
ch.GetHeading().SetColor(creator.ColorRGBFrom8bit(72, 86, 95))
// Draw subchapters.
contentAlignH(c, ch, font, fontBold)
contentAlignV(c, ch, font, fontBold)
contentWrapping(c, ch, font, fontBold)
contentOverflow(c, ch, font, fontBold)
// Draw chapter.
if err := c.Draw(ch); err != nil {
return err
}
return nil
}
func contentAlignH(c *creator.Creator, ch *creator.Chapter, font, fontBold *model.PdfFont) {
// Create subchapter.
sc := ch.NewSubchapter("Content horizontal alignment")
sc.SetMargins(0, 0, 30, 0)
sc.GetHeading().SetFont(font)
sc.GetHeading().SetFontSize(13)
sc.GetHeading().SetColor(creator.ColorRGBFrom8bit(72, 86, 95))
// Create subchapter description.
desc := c.NewStyledParagraph()
desc.SetMargins(0, 0, 10, 0)
desc.Append("Cell content can be aligned horizontally left, right or it can be centered.")
sc.Add(desc)
// Create table.
table := c.NewTable(3)
table.SetMargins(0, 0, 10, 0)
drawCell := func(text string, font *model.PdfFont, align creator.CellHorizontalAlignment) {
p := c.NewStyledParagraph()
p.Append(text).Style.Font = font
cell := table.NewCell()
cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 1)
cell.SetHorizontalAlignment(align)
cell.SetContent(p)
}
// Draw table header.
drawCell("Align left", fontBold, creator.CellHorizontalAlignmentLeft)
drawCell("Align center", fontBold, creator.CellHorizontalAlignmentCenter)
drawCell("Align right", fontBold, creator.CellHorizontalAlignmentRight)
// Draw table content.
for i := 0; i < 5; i++ {
num := i + 1
drawCell(fmt.Sprintf("Product #%d", num), font, creator.CellHorizontalAlignmentLeft)
drawCell(fmt.Sprintf("Description #%d", num), font, creator.CellHorizontalAlignmentCenter)
drawCell(fmt.Sprintf("$%d", num*10), font, creator.CellHorizontalAlignmentRight)
}
sc.Add(table)
}
func contentAlignV(c *creator.Creator, ch *creator.Chapter, font, fontBold *model.PdfFont) {
// Create subchapter.
sc := ch.NewSubchapter("Content vertical alignment")
sc.SetMargins(0, 0, 30, 0)
sc.GetHeading().SetFont(font)
sc.GetHeading().SetFontSize(13)
sc.GetHeading().SetColor(creator.ColorRGBFrom8bit(72, 86, 95))
// Create subchapter description.
desc := c.NewStyledParagraph()
desc.SetMargins(0, 0, 10, 0)
desc.Append("Cell content can be positioned vertically at the top, bottom or in the middle of the cell.")
sc.Add(desc)
// Create table.
table := c.NewTable(3)
table.SetMargins(0, 0, 10, 0)
drawCell := func(text string, font *model.PdfFont, fontSize float64, align creator.CellVerticalAlignment) {
p := c.NewStyledParagraph()
chunk := p.Append(text)
chunk.Style.Font = font
chunk.Style.FontSize = fontSize
cell := table.NewCell()
cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 1)
cell.SetVerticalAlignment(align)
cell.SetHorizontalAlignment(creator.CellHorizontalAlignmentCenter)
cell.SetContent(p)
}
// Draw table header.
drawCell("Align top", fontBold, 10, creator.CellVerticalAlignmentMiddle)
drawCell("Align bottom", fontBold, 10, creator.CellVerticalAlignmentMiddle)
drawCell("Align middle", fontBold, 10, creator.CellVerticalAlignmentMiddle)
// Draw table content.
for i := 0; i < 5; i++ {
num := i + 1
fontSize := float64(num) * 2
drawCell(fmt.Sprintf("Product #%d", num), font, fontSize, creator.CellVerticalAlignmentTop)
drawCell(fmt.Sprintf("$%d", num*10), font, fontSize, creator.CellVerticalAlignmentBottom)
drawCell(fmt.Sprintf("Description #%d", num), font, fontSize, creator.CellVerticalAlignmentMiddle)
}
sc.Add(table)
}
func contentWrapping(c *creator.Creator, ch *creator.Chapter, font, fontBold *model.PdfFont) {
// Create subchapter.
sc := ch.NewSubchapter("Content wrapping")
sc.SetMargins(0, 0, 30, 0)
sc.GetHeading().SetFont(font)
sc.GetHeading().SetFontSize(13)
sc.GetHeading().SetColor(creator.ColorRGBFrom8bit(72, 86, 95))
// Create subchapter description.
desc := c.NewStyledParagraph()
desc.SetMargins(0, 0, 10, 0)
desc.Append("Cell text content is automatically broken into lines, depeding on the cell size.")
sc.Add(desc)
// Create table.
table := c.NewTable(4)
table.SetColumnWidths(0.25, 0.2, 0.25, 0.3)
table.SetMargins(0, 0, 10, 0)
drawCell := func(text string, font *model.PdfFont, align creator.TextAlignment) {
p := c.NewStyledParagraph()
p.SetTextAlignment(align)
p.SetMargins(2, 2, 0, 0)
p.Append(text).Style.Font = font
cell := table.NewCell()
cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 1)
cell.SetContent(p)
cell.SetIndent(0)
}
// Draw table header.
drawCell("Align left", fontBold, creator.TextAlignmentLeft)
drawCell("Align center", fontBold, creator.TextAlignmentCenter)
drawCell("Align right", fontBold, creator.TextAlignmentRight)
drawCell("Align justify", fontBold, creator.TextAlignmentCenter)
// Draw table content.
content := "Maecenas tempor nibh gravida nunc laoreet, ut rhoncus justo ultricies. Mauris nec purus sit amet purus tincidunt efficitur tincidunt non dolor. Aenean nisl eros, volutpat vitae dictum id, facilisis ac felis. Integer lacinia, turpis at fringilla posuere, erat tortor ultrices orci, non tempor neque mauris ac neque. Morbi blandit ante et lacus ornare, ut vulputate massa dictum."
drawCell(content, font, creator.TextAlignmentLeft)
drawCell(content, font, creator.TextAlignmentCenter)
drawCell(content, font, creator.TextAlignmentRight)
drawCell(content, font, creator.TextAlignmentJustify)
sc.Add(table)
}
func contentOverflow(c *creator.Creator, ch *creator.Chapter, font, fontBold *model.PdfFont) {
// Create subchapter.
sc := ch.NewSubchapter("Content overflow")
sc.SetMargins(0, 0, 30, 0)
sc.GetHeading().SetFont(font)
sc.GetHeading().SetFontSize(13)
sc.GetHeading().SetColor(creator.ColorRGBFrom8bit(72, 86, 95))
// Create subchapter description.
desc := c.NewStyledParagraph()
desc.SetMargins(0, 0, 10, 0)
desc.Append("Cell text content which not fit in the available space could be truncated to fit.")
sc.Add(desc)
// Create table.
table := c.NewTable(2)
table.SetColumnWidths(0.3, 0.7)
table.SetMargins(0, 0, 10, 0)
drawCell := func(text string, font *model.PdfFont, enableWrap bool, overflow creator.TextOverflow) {
p := c.NewStyledParagraph()
p.SetEnableWrap(enableWrap)
p.SetTextOverflow(overflow)
p.SetMargins(2, 2, 0, 0)
p.Append(text).Style.Font = font
cell := table.NewCell()
cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 1)
cell.SetContent(p)
cell.SetIndent(0)
}
content := "Maecenas tempor nibh gravida nunc laoreet, ut rhoncus justo ultricies. Mauris nec purus sit amet purus tincidunt efficitur tincidunt non dolor. Aenean nisl eros, volutpat vitae dictum id, facilisis ac felis. Integer lacinia, turpis at fringilla posuere, erat tortor ultrices orci, non tempor neque mauris ac neque. Morbi blandit ante et lacus ornare, ut vulputate massa dictum."
// Draw table header.
drawCell("Overflow Visible With Wrapping", fontBold, true, creator.TextOverflowVisible)
drawCell(content, font, true, creator.TextOverflowVisible)
drawCell("Overflow Visible Without Wrapping", fontBold, true, creator.TextOverflowVisible)
drawCell(content, font, false, creator.TextOverflowVisible)
drawCell("Overflow Hidden", fontBold, true, creator.TextOverflowHidden)
drawCell(content, font, false, creator.TextOverflowHidden)
sc.Add(table)
}

The import section in lines 9-17 imports the necessary packages and libraries. The init function loads you metered license key and authenticates your request.

In lines 28-53 the main function is defined where Creator object is instantiated and the basicUsage function is called. Writing the document to file is also done in this function.

Here is a list of basic usages from the example code.

1. Content horizontal alignment

Horizontal alignment means aligning a cell content horizontally, i.e left, right or center. This is done in the function contentAlignH which is defined in lines 77-121. In this function a table with 3 columns is crated using c.NewTable(3). The anonymous function in 96-104 which is assigned to drawCell is used to draw a single table cell using the provided parameters.

In lines 107-109 the draCell function is used to draw three table cells which are used as the header row of the table. The values creator.CellHorizontalAlignmentLeft, creator.CellHorizontalAlignmentCenter and creator.CellHorizontalAlignmentRight which are passed to drawCell function are used to set the horizontal alignment of the table cell content being drawn. The loop in lines 112-118 draws the rest of the table one row at a time.

2. Content vertical alignment

Vertical alignment specifies wether a content is drawn top, middle or bottom inside a given table cell. This alignment is shown in the example code in the function contentAlignV. Here the vertical alignment is defined using creator.CellVerticalAlignmentMiddle, creator.CellVerticalAlignmentMiddle and creator.CellVerticalAlignmentMiddle which is used when calling the drawCell function in 156-158 and also in the loop in lines 161-168.

3. Content wrapping

This example shows how a text wraps into multiple lines when the cell size doesn’t fit a given text in a single line. This can be seen in the example code in lines 173-220 which is inside the function contentWrapping.

4. Content Overflow

When the text content doesn’t fit inside a table cell it can overflow. In the content overflow section of the example code it shows how to set the behavior of an overflowing text. It can be made either visible or hidden. This is done by setting SetTextOverflow method of the StyledParagraph object. This can be shown in lines 258-267 where the drawCell function is used to draw cells and their contents. The possible values that are used to set the behavior of an overflowing content are creator.TextOverflowHidden and creator.TextOverflowVisible. Their effect is, as their names indicate, making the overflowing text hidden and visible respectively. If wrapping is enabled by using SetEnableWrap method, the content is wrapped over multiple lines without being truncated.

Run the code

To create the example document run the code using the following command.

go run pdf_tables_simple.go

Sample output

PDF table simple

Got any Questions?

We're here to help you.