pdfkit/docs/table.html
2025-04-16 16:22:41 +02:00

354 lines
16 KiB
HTML

<!DOCTYPE html><html><head><meta charset="utf-8"><title>Tables in PDFKit</title><link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Source+Code+Pro:400,700|Alegreya:700|Merriweather"><link rel="stylesheet" href="/docs/css/index.css"><link rel="stylesheet" href="/docs/css/github.css"></head><body><nav class="sidebar"><ul><li><a href="/">Home</a></li><li><a href="/docs/../index.html">Documentation</a><ul><li><a href="/docs/getting_started.html">Getting Started </a></li><li><a href="/docs/paper_sizes.html">Paper Sizes</a></li><li><a href="/docs/vector.html">Vector Graphics </a></li><li><a href="/docs/text.html">Text </a></li><li><a href="/docs/images.html">Images </a></li><li><a href="/docs/outline.html">Outlines </a></li><li><a href="/docs/annotations.html">Annotations </a></li><li><a href="/docs/forms.html">Forms </a></li><li><a href="/docs/destinations.html">Destinations</a></li><li><a href="/docs/attachments.html">Attachments </a></li><li><a href="/docs/accessibility.html">Accessibility</a></li><li><a class="selected" href="/docs/table.html">Tables </a><ul><li><a href="#the_basics">The basics</a></li><li><a href="#a_simple_table">A simple table</a></li><li><a href="#defining_column_widths">Defining column widths</a></li><li><a href="#defining_row_heights">Defining row heights</a></li><li><a href="#column/row_spans">Column/row spans</a></li><li><a href="#styling">Styling</a></li><li><a href="#optional_border">Optional border</a></li><li><a href="#table_options">Table options</a></li><li><a href="#cell_options">Cell options</a></li><li><a href="#column_options">Column options</a></li><li><a href="#row_options">Row options</a></li></ul></li><li><a href="/docs/you_made_it.html">You made it!</a></li></ul></li><li><a href="/docs/guide.pdf">PDF Guide</a></li><li><a href="/examples/kitchen-sink.pdf">Example PDF</a></li><li><a href="/examples/browserify/browser.html">Interactive Browser Demo</a></li><li><a href="http://github.com/foliojs/pdfkit">Source Code</a></li></ul></nav><div class="main"><h1 id="tables_in_pdfkit">Tables in PDFKit</h1>
<h2 id="the_basics">The basics</h2>
<p>PDFKit makes adding tables to documents quite simple, and includes many options
to customize the display of the output.</p>
<h2 id="a_simple_table">A simple table</h2>
<p>Basic tables can be defined without configuration:</p>
<pre><code>doc.table({
data: [
[&#39;Column 1&#39;, &#39;Column 2&#39;, &#39;Column 3&#39;],
[&#39;One value goes here&#39;, &#39;Another one here&#39;, &#39;OK?&#39;]
]
})</code></pre>
<p>or the more verbose way</p>
<pre><code>doc.table()
.row([&#39;Column 1&#39;, &#39;Column 2&#39;, &#39;Column 3&#39;])
.row([&#39;One value goes here&#39;, &#39;Another one here&#39;, &#39;OK?&#39;])</code></pre>
<p><img src="img/19.png"/></p>
<hr/>
<h2 id="defining_column_widths">Defining column widths</h2>
<p>Tables allow you to define the widths of columns:</p>
<ul><li><code>*</code> - distributes equally, filling the whole available space (default)</li><li><code>fixed value</code> - a fixed width based on the document content</li></ul>
<p>Example:</p>
<pre><code>doc.table({
columnStyles: [100, &quot;*&quot;, 200, &quot;*&quot;],
data: [
[&quot;width=100&quot;, &quot;star-sized&quot;, &quot;width=200&quot;, &quot;star-sized&quot;],
[
&quot;fixed-width cells have exactly the specified width&quot;,
{ text: &quot;nothing interesting here&quot;, textColor: &quot;grey&quot; },
{ text: &quot;nothing interesting here&quot;, textColor: &quot;grey&quot; },
{ text: &quot;nothing interesting here&quot;, textColor: &quot;grey&quot; }
],
],
});</code></pre>
<p><img src="img/20.png"/></p>
<hr/>
<h2 id="defining_row_heights">Defining row heights</h2>
<pre><code>doc.table({
rowStyles: [20, 50, 70],
data: [
[&quot;row 1 with height 20&quot;, &quot;column B&quot;],
[&quot;row 2 with height 50&quot;, &quot;column B&quot;],
[&quot;row 3 with height 70&quot;, &quot;column B&quot;],
],
});</code></pre>
<p><img src="img/21.png"/></p>
<p>With same height:</p>
<pre><code>doc.table({
rowStyles: 40,
data: [
[&quot;row 1&quot;, &quot;column B&quot;],
[&quot;row 2&quot;, &quot;column B&quot;],
[&quot;row 3&quot;, &quot;column B&quot;],
],
});</code></pre>
<p><img src="img/22.png"/></p>
<hr/>
<p>With height from function:</p>
<pre><code>doc.table({
rowStyles: (row) =&gt; (row + 1) * 25,
data: [
[&quot;row 1&quot;, &quot;column B&quot;],
[&quot;row 2&quot;, &quot;column B&quot;],
[&quot;row 3&quot;, &quot;column B&quot;],
],
});</code></pre>
<p><img src="img/23.png"/></p>
<hr/>
<h2 id="column/row_spans">Column/row spans</h2>
<p>Each cell can set a rowSpan or colSpan</p>
<pre><code>doc.table({
columnStyles: [200, &quot;*&quot;, &quot;*&quot;],
data: [
[{ colSpan: 2, text: &quot;Header with Colspan = 2&quot; }, &quot;Header 3&quot;],
[&quot;Header 1&quot;, &quot;Header 2&quot;, &quot;Header 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[
{
rowSpan: 3,
text: &quot;rowspan set to 3\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor&quot;,
},
&quot;Sample value 2&quot;,
&quot;Sample value 3&quot;,
],
[&quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[
&quot;Sample value 1&quot;,
{
colSpan: 2,
rowSpan: 2,
text: &quot;Both:\nrowspan and colspan\ncan be defined at the same time&quot;,
},
],
[&quot;Sample value 1&quot;],
],
})</code></pre>
<p><img src="img/24.png"/></p>
<hr/>
<h2 id="styling">Styling</h2>
<p>No borders:</p>
<pre><code>doc.table({
rowStyles: { border: false },
data: [
[&quot;Header 1&quot;, &quot;Header 2&quot;, &quot;Header 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
],
})</code></pre>
<p><img src="img/25.png"/></p>
<p>Header line only:</p>
<pre><code>doc.table({
rowStyles: (i) =&gt; {
return i &lt; 1 ? { border: [0, 0, 1, 0] } : { border: false };
},
data: [
[&quot;Header 1&quot;, &quot;Header 2&quot;, &quot;Header 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
],
})</code></pre>
<p><img src="img/26.png"/></p>
<hr/>
<p>Light Horizontal lines:</p>
<pre><code>doc.table({
rowStyles: (i) =&gt; {
return i &lt; 1
? { border: [0, 0, 2, 0], borderColor: &quot;black&quot; }
: { border: [0, 0, 1, 0], borderColor: &quot;#aaa&quot; };
},
data: [
[&quot;Header 1&quot;, &quot;Header 2&quot;, &quot;Header 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
],
})</code></pre>
<p><img src="img/27.png"/></p>
<hr/>
<p>But you can provide a custom styler as well</p>
<pre><code>doc.table({
// Set the style for all cells
defaultStyle: { border: 1, borderColor: &quot;gray&quot; },
// Set the style for cells based on their column
columnStyles: (i) =&gt; {
if (i === 0) return { border: { left: 2 }, borderColor: { left: &quot;black&quot; } };
if (i === 2) return { border: { right: 2 }, borderColor: { right: &quot;black&quot; } };
},
// Set the style for cells based on their row
rowStyles: (i) =&gt; {
if (i === 0) return { border: { top: 2 }, borderColor: { top: &quot;black&quot; } };
if (i === 3) return { border: { bottom: 2 }, borderColor: { bottom: &quot;black&quot; } };
},
data: [
[&quot;Header 1&quot;, &quot;Header 2&quot;, &quot;Header 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
],
})</code></pre>
<p><img src="img/28.png"/></p>
<hr/>
<p>Zebra style</p>
<pre><code>doc.table({
rowStyles: (i) =&gt; {
if (i % 2 === 0) return { backgroundColor: &quot;#ccc&quot; };
},
data: [
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
[&quot;Sample value 1&quot;, &quot;Sample value 2&quot;, &quot;Sample value 3&quot;],
],
})</code></pre>
<p><img src="img/29.png"/></p>
<hr/>
<h2 id="optional_border">Optional border</h2>
<pre><code>doc.table({
data: [
[
{ border: [true, false, false, false], backgroundColor: &quot;#eee&quot;, text: &quot;border:\n[true, false, false, false]&quot; },
{ border: false, backgroundColor: &quot;#ddd&quot;, text: &quot;border:\nfalse&quot; },
{ border: true, backgroundColor: &quot;#eee&quot;, text: &quot;border:\ntrue&quot; },
],
[
{ rowSpan: 3, border: true, backgroundColor: &quot;#eef&quot;, text: &quot;rowSpan: 3\n\nborder:\ntrue&quot; },
{ border: undefined, backgroundColor: &quot;#eee&quot;, text: &quot;border:\nundefined (default)&quot; },
{ border: [false, false, false, true], backgroundColor: &quot;#ddd&quot;, text: &quot;border:\n[false, false, false, true]&quot; },
],
[
{ colSpan: 2, border: true, backgroundColor: &quot;#efe&quot;, text: &quot;colSpan: 2\n\nborder:\ntrue&quot; },
],
[
{ border: 0, backgroundColor: &quot;#eee&quot;, text: &quot;border:\n0 (same as false)&quot; },
{ border: [false, true, true, false], backgroundColor: &quot;#ddd&quot;, text: &quot;border:\n[false, true, true, false]&quot; },
],
],
})</code></pre>
<p><img src="img/30.png"/></p>
<hr/>
<pre><code>doc.table({
defaultStyle: { border: false, width: 60 },
data: [
[&quot;&quot;, &quot;column 1&quot;, &quot;column 2&quot;, &quot;column 3&quot;],
[
&quot;row 1&quot;,
{
rowSpan: 3,
colSpan: 3,
border: true,
backgroundColor: &quot;#ccc&quot;,
text: &quot;rowSpan: 3\ncolSpan: 3\n\nborder:\n[true, true, true, true]&quot;,
},
],
[&quot;row 2&quot;],
[&quot;row 3&quot;],
],
})</code></pre>
<p><img src="img/31.png"/></p>
<hr/>
<p>When defining multiple styles, the cells follow the precedence:</p>
<ol><li><code>defaultStyle</code></li><li><code>columnStyles</code></li><li><code>rowStyles</code></li><li><code>cellStyle</code></li></ol>
<p>so if a table was:</p>
<pre><code>doc.table({
defaultStyle: { border: 1 },
columnStyles: { border: { right: 2 } },
rowStyles: { border: { bottom: 3 } },
data: [
[{ border: { left: 4 } }]
]
})</code></pre>
<p>The resulting cell would have a style of:</p>
<pre><code>{
border: {
top: 1, // From the default
right: 2, // From the column
bottom: 3, // From the row
left: 4 // From the cell
}
}</code></pre>
<p>Internally, PDFKit keeps track of the current X and Y position of table as it
is added to the document. This way, any calls to <code>text</code> or <code>table</code> will be placed below the table row.</p>
<pre><code>doc
.text(&#39;before&#39;)
.table({
data: [
[&#39;Column 1&#39;, &#39;Column 2&#39;, &#39;Column 3&#39;],
[&#39;One value goes here&#39;, &#39;Another one here&#39;, &#39;OK?&#39;]
]
})
.text(&#39;after&#39;)</code></pre>
<p><img src="img/32.png"/></p>
<h2 id="table_options">Table options</h2>
<ul><li><code>position</code> - The position of the table (default <code>{x: doc.x, y: doc.y}</code>)</li><li><code>maxWidth</code> - The maximum width the table can expand to (defaults to the remaining content width (offset from the tables position))</li><li><code>columnStyles</code> - Column definitions of the table. (default <code>auto</code>)</li><li><code>rowStyles</code> - Row definitions of the table. (default <code>*</code>)</li><li><code>defaultStyle</code> - Defaults to apply to every cell</li><li><code>data</code> - The data to render (not required, you can call <code>.row()</code>). This can be an iterable (async or sync)</li><li><code>debug</code> - Whether to show the debug lines for all the cells (default <code>false</code>)</li></ul>
<h2 id="cell_options">Cell options</h2>
<ul><li><code>text</code> - The value, will be cast to a string (<code>null</code> and <code>undefined</code> are not rendered but the cell is still outlined)</li><li><code>rowSpan</code> - How many rows this cell covers, follows the same logic as HTML <code>rowspan</code></li><li><code>colSpan</code> - How many columns this cell covers, follows the same logic as HTML <code>colspan</code></li><li><code>padding</code> - The padding for the cell (default <code>0.25em</code>)</li><li><code>border</code> - The border for the cell (default <code>1pt</code>)</li><li><code>borderColor</code> - The border colors for the cell (default <code>black</code>)</li><li><code>font</code> - Font options for the cell</li><li><code>backgroundColor</code> - Set the background color of the cell</li><li><code>align</code> - The alignment of the cell text (default <code>{x: &#39;left&#39;, y: &#39;top&#39;}</code>)</li><li><code>textStroke</code> - The text stroke (default <code>0</code>)</li><li><code>textStrokeColor</code> - Sets the text stroke color of the cells text (default <code>black</code>)</li><li><code>textColor</code> - Sets the text color of the cells text (default <code>black</code>)</li><li><code>type</code> - Sets the cell type (for accessibility) (default <code>TD</code>)</li><li><code>textOptions</code> - Sets any text options you wish to provide (such as rotation)</li><li><code>debug</code> - Whether to show the debug lines for the cell (default <code>false</code>)</li></ul>
<h2 id="column_options">Column options</h2>
<p>Extends the <a href="#cell-options">cell options</a> above with:</p>
<ul><li><code>width</code> - The width of the column (default <code>*</code>)</li><li><code>minWidth</code> - The minimum width of the column (default <code>0</code>)</li><li><code>maxWidth</code> - The maximum width of the column (default <code>Infinity</code>)</li></ul>
<h2 id="row_options">Row options</h2>
<p>Extends the <a href="#cell-options">cell options</a> above with:</p>
<ul><li><code>height</code> - The height of the row (default <code>auto</code>)</li><li><code>minHeight</code> - The minimum height of the row (default <code>0</code>)</li><li><code>maxHeight</code> - The maximum height of the row (default <code>Infinity</code>)</li></ul><nav><a class="previous" href="/docs/accessibility.html">Previous</a><a class="next" href="/docs/you_made_it.html">Next</a></nav></div><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script><script src="/docs/js/scroll.js"></script><script src="/docs/js/highlight.pack.js"></script><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-48340245-1', 'pdfkit.org');
ga('send', 'pageview');</script></body></html>