line-by-line-pdf-generator
v1.2.1
Published
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!
Maintainers
Readme
📄 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-generatorUsage
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
TEXTIMAGEEMPTYPAGE_BREAKPAGE_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!"
}],
]