# How to Use Columns in PDFMake with html-to-pdfmake

> Learn to create PDFMake columns using html-to-pdfmake. Effortlessly convert divs into columns with data-pdfmake-type attributes for simple PDF layout control.

- Repository: [Aymeric/html-to-pdfmake](https://github.com/aymkdn/html-to-pdfmake)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Use the `data-pdfmake-type="columns"` attribute on a `<div>` element to convert its children into a PDFMake `columns` array, with optional width control via `data-pdfmake` attributes or inline styles.**

The `aymkdn/html-to-pdfmake` library transforms standard HTML into PDFMake document definitions. When you need side-by-side layouts in your generated PDFs, the library provides a declarative way to use columns in PDFMake with html-to-pdfmake through data attributes rather than writing complex JavaScript object structures.

## Understanding the Columns Feature

PDFMake supports a `columns` layout that places elements horizontally next to each other. In `html-to-pdfmake`, you trigger this behavior by adding a specific data attribute to a container div. When the parser encounters a `<div>` with `data-pdfmake-type="columns"`, it treats each direct child element as a separate column in the resulting PDF.

According to the source code in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js), the parser checks for this attribute inside the `default` branch of the `switch(nodeName)` block during the recursive DOM traversal performed by `parseElement`.

## Implementing Columns with data-pdfmake-type

### Basic Syntax

Wrap your column content in a parent div with the columns attribute:

```html
<div data-pdfmake-type="columns">
  <div>First column content</div>
  <div>Second column content</div>
</div>

```

The library converts this into a PDFMake structure where each child becomes an entry in the `columns` array. During parsing, the library builds a temporary `stack` containing the processed children, then moves this stack to `ret.columns` and deletes the temporary `stack` property.

### Controlling Column Widths

You can declare column widths using three methods:

- **`data-pdfmake='{"width":"*"}'`** – Explicitly sets width to star (remaining space), auto, or a fixed unit
- **`style="width:auto"`** – Extracts the style value and normalizes it into the width property
- **No declaration** – Inherits default PDFMake auto-sizing behavior

The parser extracts these values during the conversion process and applies them to the resulting column definitions.

## Code Examples

### Two Equal-Width Columns

Create a balanced two-column layout using star widths:

```html
<div data-pdfmake-type="columns">
  <div data-pdfmake='{"width":"*"}'>
    <p>Left column content with flexible width</p>
  </div>
  <div data-pdfmake='{"width":"*"}'>
    <p>Right column content with flexible width</p>
  </div>
</div>

```

**Resulting PDFMake definition:**

```json
{
  "columns": [
    { "width": "*", "stack": [{ "text": "Left column content with flexible width" }] },
    { "width": "*", "stack": [{ "text": "Right column content with flexible width" }] }
  ]
}

```

### Mixed Width Configurations

Combine fixed, auto, and default sizing in a single row:

```html
<div data-pdfmake-type="columns">
  <div data-pdfmake='{"width":"150"}'>Fixed 150 points</div>
  <div style="width:auto">Auto-sized based on content</div>
  <div>Default auto behavior</div>
</div>

```

This generates columns with specific measurements while letting PDFMake handle the remaining space automatically.

### Nesting Columns Inside Tables

Columns work within any PDFMake container, including table cells:

```html
<table>
  <tr>
    <td>
      <div data-pdfmake-type="columns">
        <div data-pdfmake='{"width":"*"}'>Column A</div>
        <div data-pdfmake='{"width":"*"}'>Column B</div>
      </div>
    </td>
  </tr>
</table>

```

The resulting structure places a `columns` array inside the table body definition, allowing complex grid layouts within tabular data.

### Node.js and Browser Implementation

**Node.js with jsdom:**

```javascript
const htmlToPdfMake = require('html-to-pdfmake');
const { JSDOM } = require('jsdom');

const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');
const html = `
  <div data-pdfmake-type="columns">
    <div data-pdfmake='{"width":"*"}'>Server-side column 1</div>
    <div data-pdfmake='{"width":"*"}'>Server-side column 2</div>
  </div>
`;

const docDefinition = htmlToPdfMake(html, { window: dom.window });
console.log(JSON.stringify(docDefinition, null, 2));

```

**Browser environment:**

```javascript
const docDefinition = htmlToPdfMake(
  document.getElementById('source').innerHTML, 
  { window: window }
);

pdfMake.createPdf(docDefinition).open();

```

The `window` option supplies the DOM environment required for parsing. In Node.js, libraries like `jsdom` provide this interface.

## Technical Implementation Details

The column conversion logic resides in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) within the `parseElement` function. Specifically, in the `default` case of the node name switch block (lines 581-588), the code checks `element.dataset.pdfmakeType === "columns"`.

When this condition matches:

1. The parser processes all child nodes into a temporary `stack` array
2. It assigns this stack to `ret.columns`
3. It removes the temporary `stack` property from the return object
4. Each child's width configuration is extracted from `data-pdfmake` attributes or inline styles

This approach allows the library to support complex nested structures where columns contain tables, images, or additional nested columns.

## Validation and Testing

The unit test suite in [`test/unit.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/test/unit.js) (lines 16-31) validates the column functionality. The test verifies that HTML containing the columns attribute generates a proper `columns` array with three items and correctly parses various width specifications, including JSON in data attributes and CSS-style width declarations.

The test confirms that width values are properly extracted whether specified via `data-pdfmake='{"width":"*"}'` or `style="width:auto"`, ensuring consistent behavior across different markup styles.

## Summary

- Add `data-pdfmake-type="columns"` to a `<div>` to enable PDFMake column layouts
- Each direct child becomes a separate column in the generated PDF
- Control widths using `data-pdfmake` attributes (e.g., `{"width":"*"}`), inline styles (e.g., `width:auto`), or leave unspecified for default sizing
- The conversion happens in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) during the `parseElement` recursive traversal
- Columns function correctly when nested inside tables, stacks, or other containers
- Supply a `window` object when running in Node.js environments

## Frequently Asked Questions

### What is the exact HTML attribute needed to create columns?

Add `data-pdfmake-type="columns"` to a parent `<div>` element. When the parser processes this div in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js), it recognizes the special type and converts the element's children into a PDFMake `columns` array instead of a vertical stack.

### How do I set column widths using html-to-pdfmake?

Use one of three methods: apply `data-pdfmake='{"width":"*"}'` for star sizing, `data-pdfmake='{"width":"auto"}'` for automatic sizing, or `style="width:150"` for fixed units. The parser extracts these values during the conversion process defined in the default branch of the element handler.

### Can columns be nested inside tables or other elements?

Yes, columns work within any valid PDFMake container. You can place a `data-pdfmake-type="columns"` div inside table cells (`<td>`), list items, or other structural elements. The library recursively processes the DOM tree, so nested columns generate properly structured PDFMake definitions at any depth.

### Does this work in Node.js environments?

Yes, but you must provide a DOM environment since the library uses `DOMParser` internally. Pass a `window` object from `jsdom` or similar libraries in the options parameter: `htmlToPdfMake(html, { window: dom.window })`. Without this, the parser cannot parse the HTML string into a traversable DOM tree.