Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
jspdf-autotable
Advanced tools
jspdf-autotable is an npm package that allows you to create tables in PDF documents using jsPDF. It provides a simple API to generate tables with various customization options, including styling, headers, footers, and more.
Basic Table
This feature allows you to create a basic table with headers and rows. The `head` property defines the table headers, and the `body` property defines the table rows.
const { jsPDF } = require('jspdf');
require('jspdf-autotable');
const doc = new jsPDF();
doc.autoTable({
head: [['Name', 'Email', 'Country']],
body: [
['John Doe', 'john@example.com', 'USA'],
['Jane Doe', 'jane@example.com', 'Canada'],
],
});
doc.save('table.pdf');
Custom Styling
This feature allows you to apply custom styling to the table, including the table body, headers, and alternate rows. The `styles`, `headStyles`, and `alternateRowStyles` properties are used to define the styles.
const { jsPDF } = require('jspdf');
require('jspdf-autotable');
const doc = new jsPDF();
doc.autoTable({
head: [['Name', 'Email', 'Country']],
body: [
['John Doe', 'john@example.com', 'USA'],
['Jane Doe', 'jane@example.com', 'Canada'],
],
styles: { fillColor: [255, 0, 0] },
headStyles: { fillColor: [0, 255, 0] },
alternateRowStyles: { fillColor: [255, 255, 0] },
});
doc.save('styled_table.pdf');
Column and Row Spanning
This feature allows you to create tables with cells that span multiple columns or rows. The `colSpan` and `rowSpan` properties are used to define the spanning.
const { jsPDF } = require('jspdf');
require('jspdf-autotable');
const doc = new jsPDF();
doc.autoTable({
head: [['Name', 'Email', 'Country']],
body: [
[{ content: 'John Doe', colSpan: 2 }, 'USA'],
['Jane Doe', { content: 'jane@example.com', rowSpan: 2 }, 'Canada'],
['Another Jane', ''],
],
});
doc.save('spanning_table.pdf');
pdfmake is a powerful library for creating PDF documents in JavaScript. It offers a wide range of features, including table creation, custom styling, and more. Compared to jspdf-autotable, pdfmake provides more comprehensive document creation capabilities but may have a steeper learning curve.
pdfkit is a PDF document generation library for Node.js. It allows you to create complex PDF documents with text, images, tables, and more. While it offers similar table creation functionalities, it requires more manual setup compared to jspdf-autotable.
Puppeteer is a Node library that provides a high-level API to control Chrome or Chromium over the DevTools Protocol. It can be used to generate PDFs from HTML content, including tables. While it is not specifically designed for table creation, it offers a flexible way to generate PDFs from web content.
Generate PDF tables with Javascript
This jsPDF plugin adds the ability to generate PDF tables either by parsing HTML tables or by using Javascript data directly. Check out the demo or examples.
Get jsPDF and this plugin by doing one of these things:
npm install jspdf jspdf-autotable
import jsPDF from 'jspdf'
import autoTable from 'jspdf-autotable'
const doc = new jsPDF()
// It can parse html:
// <table id="my-table"><!-- ... --></table>
autoTable(doc, { html: '#my-table' })
// Or use javascript directly:
autoTable(doc, {
head: [['Name', 'Email', 'Country']],
body: [
['David', 'david@example.com', 'Sweden'],
['Castille', 'castille@example.com', 'Spain'],
// ...
],
})
// Sometimes you might have to call the default function on the export (for example in Deno)
autoTable.default(doc, { html: '#my-table' })
doc.save('table.pdf')
You can also use the plugin methods directly on the jsPDF documents:
import jsPDF from 'jspdf'
import 'jspdf-autotable'
const doc = new jsPDF()
doc.autoTable({ html: '#my-table' })
doc.save('table.pdf')
The third usage option is with downloaded or CDN dist files
<script src="jspdf.min.js"></script>
<script src="jspdf.plugin.autotable.min.js"></script>
<script>
var doc = new jsPDF()
doc.autoTable({ html: '#my-table' })
doc.save('table.pdf')
</script>
Checkout more examples in examples.js which is also the source code for the demo documents.
Below is a list of all options supported in the plugin. All of them are used in the examples.
The only thing required is either the html or body option. If you want more control over the columns you can specify the columns property. If columns are not set they will be automatically computed based on the content of the html content or head, body and foot.
html: string|HTMLTableElement
A css selector (for example "#table") or an html table element.head: CellDef[][]
For example [['ID', 'Name', 'Country']]body: CellDef[][]
For example [['1', 'Simon', 'Sweden'], ['2', 'Karl', 'Norway']]foot: CellDef[][]
For example [['ID', 'Name', 'Country']]columns: ColumnDef[]
For example [{header: 'ID', dataKey: 'id'}, {header: 'Name', dataKey: 'name'}]. Only use this option if you want more control over the columns. If not specified the columns will be automatically generated based on the content in html or head/body/footincludeHiddenHtml: boolean = false
If hidden html with display: none
should be included or not when the content comes from an html tableCellDef: string|{content: string, rowSpan: number, colSpan: number, styles: StyleDef}
Note that cell styles can also be set dynamically with hooks.
ColumnDef: string|{header?: string, dataKey: string}
The header property is optional and the values of any content in head
will be used if not set. Normally it's easier to use the html or head/body/foot style of initiating a table, but columns can be useful if your body content comes directly from an api or if you would like to specify a dataKey on each column to make it more readable to style specific columns in the hooks or columnStyles.
Usage with colspan, rowspan and inline cell styles:
autoTable(doc, {
body: [
[{ content: 'Text', colSpan: 2, rowSpan: 2, styles: { halign: 'center' } }],
],
})
theme: 'striped'|'grid'|'plain' = 'striped'
styles: StyleDef
headStyles: StyleDef
bodyStyles: StyleDef
footStyles: StyleDef
alternateRowStyles: StyleDef
columnStyles: {&columnDataKey: StyleDef}
Note that the columnDataKey is normally the index of the column, but could also be the dataKey
of a column if content initialized with the columns propertyStyleDef
:
font: 'helvetica'|'times'|'courier' = 'helvetica'
fontStyle: 'normal'|'bold'|'italic'|'bolditalic' = 'normal'
overflow: 'linebreak'|'ellipsize'|'visible'|'hidden' = 'linebreak'
fillColor: Color? = null
textColor: Color? = 20
cellWidth: 'auto'|'wrap'|number = 'auto'
minCellWidth: number? = 10
minCellHeight: number = 0
halign: 'left'|'center'|'right' = 'left'
valign: 'top'|'middle'|'bottom' = 'top'
fontSize: number = 10
cellPadding: Padding = 10
lineColor: Color = 10
lineWidth: border = 0
// If 0, no border is drawnColor
:
Either false for transparent, hex string, gray level 0-255 or rbg array e.g. [255, 0, 0]
false|string|number|[number, number, number]
Padding
:
Either a number or object {top: number, right: number, bottom: number, left: number}
border
:
Either a number or object {top: number, right: number, bottom: number, left: number}
Styles work similar to css and can be overridden by more specific styles. Overriding order:
styles
headStyles
, bodyStyles
and footStyles
alternateRowStyles
columnStyles
Styles for specific cells can also be applied using either the hooks (see hooks section above) or the styles
property on the cell definition object (see content section above).
Example usage of column styles (note that the 0 in the columnStyles below should be dataKey if columns option used)
// Example usage with columnStyles,
autoTable(doc, {
styles: { fillColor: [255, 0, 0] },
columnStyles: { 0: { halign: 'center', fillColor: [0, 255, 0] } }, // Cells in first column centered and green
margin: { top: 10 },
body: [
['Sweden', 'Japan', 'Canada'],
['Norway', 'China', 'USA'],
['Denmark', 'China', 'Mexico'],
],
})
// Example usage of columns property. Note that America will not be included even though it exist in the body since there is no column specified for it.
autoTable(doc, {
columnStyles: { europe: { halign: 'center' } }, // European countries centered
body: [
{ europe: 'Sweden', america: 'Canada', asia: 'China' },
{ europe: 'Norway', america: 'Mexico', asia: 'Japan' },
],
columns: [
{ header: 'Europe', dataKey: 'europe' },
{ header: 'Asia', dataKey: 'asia' },
],
})
useCss: boolean = false
startY: number = null
Where the table should start to be printed (basically a margin top value only for the first page)margin: Margin = 40
pageBreak: 'auto'|'avoid'|'always'
If set to avoid
the plugin will only split a table onto multiple pages if table height is larger than page height.rowPageBreak: 'auto'|'avoid' = 'auto'
If set to avoid
the plugin will only split a row onto multiple pages if row height is larger than page height.tableWidth: 'auto'|'wrap'|number = 'auto'
showHead: 'everyPage'|'firstPage'|'never' = 'everyPage''
showFoot: 'everyPage'|'lastPage'|'never' = 'everyPage''
tableLineWidth: number = 0
tableLineColor: Color = 200
The table line/border colorhorizontalPageBreak: boolean = false
To split/break the table into multiple pages if the given table width exceeds the page widthhorizontalPageBreakRepeat: string|number|string[]|number[]
To repeat the given column in the split pages, works when horizontalPageBreak = true
. The accepted values are column dataKeys, such as 'id'
, recordId
or column indexes, such as 0
, 1
or array for multiple columns.horizontalPageBreakBehaviour: 'immediately'|'afterAllRows' = 'afterAllRows'
How the horizontal page breaks behave, works when horizontalPageBreak = true
Margin
:
Either a number or object {top: number, right: number, bottom: number, left: number}
You can customize the content and styling of the table by using the hooks. See the custom styles example for usage of the hooks.
didParseCell: (HookData) => {}
- Called when the plugin finished parsing cell content. Can be used to override content or styles for a specific cell.willDrawCell: (HookData) => {}
- Called before a cell or row is drawn. Can be used to call native jspdf styling functions such as doc.setTextColor
or change position of text etc before it is drawn.didDrawCell: (HookData) => {}
- Called after a cell has been added to the page. Can be used to draw additional cell content such as images with doc.addImage
, additional text with doc.addText
or other jspdf shapes.willDrawPage: (HookData) => {}
- Called before starting to draw on a page. Can be used to add headers or any other content that you want on each page there is an autotable.didDrawPage: (HookData) => {}
- Called after the plugin has finished drawing everything on a page. Can be used to add footers with page numbers or any other content that you want on each page there is an autotable.All hooks functions get passed an HookData object with information about the state of the table and cell. For example the position on the page, which page it is on etc.
HookData
:
table: Table
pageNumber: number
The page number specific to this tablesettings: object
Parsed user supplied optionsdoc
The jsPDF document instance of this tablecursor: { x: number, y: number }
To draw each table this plugin keeps a cursor state where the next cell/row should be drawn. You can assign new values to this cursor to dynamically change how the cells and rows are drawn.For cell hooks these properties are also passed:
cell: Cell
row: Row
column: Column
section: 'head'|'body'|'foot'
To see what is included in the Table
, Row
, Column
and Cell
types, either log them to the console or take a look at src/models.ts
// Example with an image drawn in each cell in the first column
autoTable(doc, {
didDrawCell: (data) => {
if (data.section === 'body' && data.column.index === 0) {
var base64Img = 'data:image/jpeg;base64,iVBORw0KGgoAAAANS...'
doc.addImage(base64Img, 'JPEG', data.cell.x + 2, data.cell.y + 2, 10, 10)
}
},
})
doc.autoTable({ /* options */ })
autoTable(doc, { /* options */ })
jsPDF.autoTableSetDefaults({ /* ... */ })
Use for setting global defaults which will be applied for all tablesIf you want to know something about the last table that was drawn you can use doc.lastAutoTable
. It has a doc.lastAutoTable.finalY
property among other things that has the value of the last printed y coordinate on a page. This can be used to draw text, multiple tables or other content after a table.
In addition to the exported autoTable(doc, options) method you can also use applyPlugin to add the autoTable api to any jsPDF instance.
import jsPDF from 'jspdf/dist/jspdf.node.debug'
import { applyPlugin } from 'jspdf-autotable'
applyPlugin(jsPDF)
Contributions are always welcome, especially on open issues. If you have something major you want to add or change, please post an issue about it first to discuss it further. The workflow for contributing would be something like this:
npm start
If you don't use Prettier on autosave, please run yarn run format-all
before opening your PR
npm version <semver>
and npm run deploy)PR=472 npm run checkout-pr
npm version prerelease
git push && git push --tags && npm publish --tag alpha
FAQs
Generate pdf tables with javascript (jsPDF plugin)
We found that jspdf-autotable demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.