line-by-line-pdf-generator
TypeScript icon, indicating that this package has built-in type declarations

1.2.1 • Public • Published

📄 Line by line PDF generator for Node

An easy to use Line by Line pdf generator for NodeJS using PDFKit, with support of text, images, backgrounds, borders, and page layout control without needing a browser engine installed!

Features

  • Dynamic layout with rows and columns
  • Support for text, images, and layout control (page breaks, splits, etc.)
  • Customizable styling (fonts, colors, borders, margins)
  • Get PDF as a buffer as a return
  • No need for a browser engine to be installed

Installation

npm install line-by-line-pdf-generator

Usage

You can run the generatePdf function it expects 2 arguments, the first one is a 2-dimensional array with all the columns and the second one is optional and is the options for the pdf.

import pdfGenerator from "line-by-line-pdf-generator"


const generatedPdf = await pdfGenerator([
    [
        /* PDF columns for the first row */
    ],
    [
        /* PDF columns for the second row */
    ]
], {
    /* Optional options */
})

Example

An example of a very simple PDF

import pdfGenerator from "line-by-line-pdf-generator"
import {PdfColumnType} from "line-by-line-pdf-generator/types";

import fs from "fs"

const generatedPdf = await pdfGenerator([
    [
        {
            type: PdfColumnType.TEXT,
            text: "Hello world",
            justify: "center",
        },
        {
            type: PdfColumnType.EMPTY,
            cols: 2
        },
        {
            type: PdfColumnType.TEXT,
            text: "Goodbye",
        },
    ],
    [
        {
            type: PdfColumnType.TEXT,
            text: "Image: ",
            size: 24,
            justify: "left",
            color: "black",
            background: "yellow"
        },
        {
            type: PdfColumnType.IMAGE,
            cols: 3,
            url: "https://picsum.photos/300/200",
            options: {
                fit: ["colum-width", 300]
            }
        },
    ]
], {
    textColor: "green",
    textJustify: "right"
})


fs.writeFileSync("pdf.pdf", generatedPdf)

Options

The PDF options exists of the following arguments all of these are optional

Option Type Default Description
margin number 30 A margin on the pdf page
rowHeight number 1 The amount of pixels on the top and bottom of texts columns
colMargin number 0 The amount of pixels on the right and left of texts columns
textSize number 12 The default font size of text
textColor string black The default text color
textFont string Helvetica The default font
textJustify TextJustify left The justify for all text (see text columns for more info)

Rows and columns

To create a PDF with the line by line PDF generator you have to use a 2-dimensional array of Rows containing Columns, think of it like this

[
    [{ /* First col of the first line*/}, { /* Second col of the first line*/}], /* First line of the PDF*/
    [{ /* First col of the second line*/}, { /* Second col of the second line*/}] /* Second line of the PDF*/
]

The location if the columns will be automatically calculated. There are multiple column types

  • TEXT
  • IMAGE
  • EMPTY
  • PAGE_BREAK
  • PAGE_SPLIT

Each of these have their own unique features but all of them have common attributes that can be used by any of them

Common column attributes

These attributes can be used by all column types:

Background

The background of the column, it can be any a color name or a hex value

Example

const yellowColumn = {
    type: PdfColumnType.EMPTY,
    background: "yellow"
}

Border

The Border of the column, it has 4 optional sub attributes left, right, top, and bottom they indicate the axes of the border each axes has 2 attributes width and an optional color, width is the size of the border and color is the border color with will default to the font color

Example

const borderedColumn = {
    type: PdfColumnType.EMPTY,
    border: {
        top: {
            width: 1,
            color: "black"
        },
        bottom: {
            width: 1,
            color: "black"
        },
        left: {
            width: 1,
            color: "black"
        },
        right: {
            width: 1,
            color: "black"
        }
    }
}

cols

The width of Columns by default is all the same, but sometimes you want some colums to be bigger or smaller than other columns, you can use the cols attribute for that, cols is a number with default 1 that indicates the size this column indicates, if cols is 2 it will be twice as big as the default.

Example

const differentSizeRow = [
    {
        type: PdfColumnType.EMPTY,
        cols: 1 /* this col will take 25% of the page */
    },
    {
        type: PdfColumnType.EMPTY,
        cols: 2 /* this col will take 50% of the page */
    },
    {
        type: PdfColumnType.EMPTY,
        cols: 1 /* this col will take 25% of the page */
    }
]

you can also make cols intentionally smaller

const differentSizeRow = [
    {
        type: PdfColumnType.EMPTY,
        cols: 1 /* this col will take 50% of the page */
    },
    {
        type: PdfColumnType.EMPTY,
        cols: 0.5 /* this col will take 25% of the page */
    },
    {
        type: PdfColumnType.EMPTY,
        cols: 0.5 /* this col will take 25% of the page */
    }
]

Be aware that cols: 1 is the default so its not necessary to include, I only included it for extra clarity

Text column

Adds texts to the column, text will not exceed a size of a column and will be wrapped inside the column, the height will be automatically be taken care off. A text column can have the following attributes:

text

This is a required string, that will be the text that is placed in the column, it will be automatically wrapped to the size of the column

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Hello world"
}

link

An oprional string to make text a clickable link.

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Go to my website!",
    link: "https://michelle-honnebier.com"
}

color

An optional string of the color of the text will default to the textColor value in the PDF options, color can be a color name or HEX value.

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Hello world",
    color: "green"
}

size

An optional string of the color of the text will default to the textSize value in the PDF options

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Hello world!",
    size: 36
}

font

An optional string of the font of the text will default to the textFont value in the PDF options learn more about fonts here for now you can only use the default fonts the ability to register new fonts will be availible soon

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Hello world",
    font: "Helvatica-Bolt",
}

justify

An optinal value that is indicate how the text can be aligned in the column it can be left, center, right, or justify. It will fallback to the textJustify value in the PDF options. read more about it here

Example

const textColumn = {
    type: PdfColumnType.TEXT,
    text: "Hello world",
    justify: "right",
}

Empty column

Empty columns are columns without anything, they can be used to create a buffer or make use of the common attributes to get a background text, it has one attribute sizewhich is the size in pixels how big the empty column.

Examples

You can use empty column to create a vertical buffer

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }],
    [{
        type: PdfColumnType.EMPTY,
        size: 150 /* 150px empty space between rows*/
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }]
]

You can also use empty column to use default attributes and align all your columns correctly

const PdfRow = [
    {
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }, {
        type: PdfColumnType.EMPTY,
        cols: 2,
        color: "yellow" /* ads an empty yellow block between the 2 texts that takes 50% of the page */
    }, {
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }
]

Image column

Image columns can be used to insert images, it expects an attribute url, file, or buffer and options, url, file, or buffer is how the image should be fetched url points to a url file points to a file, and buffer is an ArrayBuffer of the image, options are the PDFKIT image options, If you want to use the column with as image with you can use the "column-with" string and it will be replaced by the column with, currently only width and fit are supported, more support is coming soon

Examples

Simple image from an url:

const imageColumn = {
    type: PdfColumnType.IMAGE,
    cols: 3,
    url: "https://picsum.photos/300/200",
    options: {
        width: 300,
        height: 200
    }
}

Simple image from a file:

const imageColumn = {
  type: PdfColumnType.IMAGE,
  cols: 3,
  file: "assets/images/logo.png",
  options: {
    width: 300,
    height: 200
  }
}

Simple image from a buffer:

const imageColumn = {
  type: PdfColumnType.IMAGE,
  cols: 3,
  buffer: <ArrayBuffer>,
  options: {
    width: 300,
    height: 200
  }
}

Image to fit in specific width and height:

const imageColumn = {
    type: PdfColumnType.IMAGE,
    cols: 3,
    url: "https://picsum.photos/300/200",
    options: {
        fit: [300, 200],
    }
}

Image to within column width:

const imageColumn = {
    type: PdfColumnType.IMAGE,
    cols: 3,
    url: "https://picsum.photos/300/200",
    options: {
        fit: ["column-width", 200],
    }
}

⚠️ Caveats

Images will not have their height calculated within the row height, this is intended behaviour since its quite common you want multiple text rows next to an image, if you want to text below an image you can create an Empty column with cols: 0 and size: image-size to make the height of the row the height of the image, a way to calculate the image height in the row height is coming soon.

Page break

End of page will end the page, all following rows will appear on a new page

Examples

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This will appear on page one */
    }],
    [{
        type: PdfColumnType.PAGE_BREAK,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will appear on page two */
    }]
]

You can also use default attributes on a page break

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This will appear on page one */
    }],
    [{
        type: PdfColumnType.EMPTY,
    }, {
        type: PdfColumnType.PAGE_BREAK,
        background: "blue",
        cols: 2 /* 66% of the rest of the page will a blue block*/
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will appear on page two */
    }]
]

Page split

Will create a split in the page, the lines after a split will be rendered on the bottom of the page, if the 2 sections do not fit on one page a new page will be created.

Examples

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This on top */
    }], [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This one line below*/
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will one line above the the bottom of the page */
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will appear on the bottom of the age */
    }]
]

If the 2 sections are to big for one page it will look like this

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This on top */
    }], [{
        type: PdfColumnType.EMPTY,
        size: 1000
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This be on top of a new page  */
    }],
    [{
        type: PdfColumnType.EMPTY,
        size: 1000
    }]
]

You can also use page split columns with the common attributes

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This on top */
    }], [{
        type: PdfColumnType.TEXT,
        text: "Hello world" /* This one line below*/
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
        background: "orange",
        border: {
            bottom: {
                width: 1,
                color: white
            }
        } /* The space between the sections will be orange and there will be a white border before the second section */
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will one line above the the bottom of the page */
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"  /* This will appear on the bottom of the age */
    }]
]

⚠️ Caveats

You can only use one page split per page, if you want to use another one you need to place an PAGE_BREAK component between them

This will give an error:

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }], [{
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }]
]

This will work fine

const PdfRows = [
    [{
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }], [{
        type: PdfColumnType.TEXT,
        text: "Hello world"
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.PAGE_BREAK,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.PAGE_SPLIT,
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
    [{
        type: PdfColumnType.TEXT,
        text: "Goodbye!"
    }],
]

Package Sidebar

Install

npm i line-by-line-pdf-generator

Weekly Downloads

21

Version

1.2.1

License

MIT

Unpacked Size

47.3 kB

Total Files

9

Last publish

Collaborators

  • michellex98