Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/schibsted/jsx-pdf

Generate PDFs using JSX! 🎯
https://github.com/schibsted/jsx-pdf

jsx pdf pdf-generation pdfmake

Last synced: 4 days ago
JSON representation

Generate PDFs using JSX! 🎯

Lists

README

        

![jsx-pdf logo](https://user-images.githubusercontent.com/11426386/43649419-0819a78a-9735-11e8-8a74-12d26e5e830b.jpg)

[![npm version](https://badge.fury.io/js/jsx-pdf.svg)](https://www.npmjs.com/jsx-pdf) [![Build Status](https://travis-ci.org/schibsted/jsx-pdf.svg?branch=master)](https://travis-ci.org/schibsted/jsx-pdf) [![Coverage Status](https://coveralls.io/repos/github/schibsted/jsx-pdf/badge.svg?branch=master)](https://coveralls.io/github/schibsted/jsx-pdf?branch=master)

Generate modular PDFs via [pdfmake](http://pdfmake.org/) using JSX.

```jsx
import PDFMake from 'pdfmake';
import JsxPdf from 'jsx-pdf';
import { OpenSans } from './font-descriptors';

const pdfMake = new PDFMake({
OpenSans,
});

const stream = pdfMake.createPdfKitDocument(
JsxPdf.renderPdf(

This will appear in my PDF!
,
),
);

// write the stream to a file; this could also be streamed to an HTTP connection, stdout etc
stream.on('end', () => console.log('PDF generated'));
stream.pipe(fs.createWriteStream('~/Desktop/test.pdf'));
stream.end();
```

## Quick start

### Javascript

- `yarn add jsx-pdf @babel/plugin-transform-react-jsx`
- Configure the part of your build that transpiles your JSX to use `JsxPdf.createElement` as the element factory.
- For babel, add the configuration below to your `.babelrc`.
```json
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{ "pragma": "JsxPdf.createElement", "pragmaFrag": "JsxPdf.Fragment" }
]
]
```

### Typescript

- `yarn add -D @types/jsx-pdf`
- For TypeScript, add the configuration below to your `tsconfig.json`. Setting `jsx` to `react` configures TypeScript to handle JSX transpiling for you, and the `jsxFactory` option specifies the element factory to use. Setting `jsxFragmentFactory` allows you to use [JSX Fragments](https://reactjs.org/docs/fragments.html#short-syntax).

```json
"compilerOptions": {
"jsx": "react",
"jsxFactory": "JsxPdf.createElement",
"jsxFragmentFactory": "JsxPdf.Fragment",
},
```

- Code away! See the examples below.

You can also run our example script by running `yarn demo` and opening the generated pdf at `example/example.pdf`. Check the console logs for additional information.

## Components

Similar to modern front-end frameworks, you can define your own components using declarative syntax.

#### Basic example:

```jsx
import JsxPdf from 'jsx-pdf';

const Greeting = ({ name }) => Hello, {name}!;

const doc = (





);
```

#### List example:

```jsx
import JsxPdf from 'jsx-pdf';

const GroupGreeting = ({ names }) => (
<>
{names.map((name) => (

))}
>
);

const doc = (





);
```

#### Inline If example:

```jsx
import JsxPdf from 'jsx-pdf';

const Signature = () => JSX-PDF, Inc.;

const SignedGreeting = ({ name }) => (
<>
{name && }

>
);

const doc = (





);
```

#### Inline If-Else example:

```jsx
import JsxPdf from 'jsx-pdf';

const AnonymousGreeting = () => We don't know you.;

const SignedGreeting = ({ name }) => (
<>
{name ? : }

>
);

const doc = (





);
```

#### Element variable example:

```jsx
import JsxPdf from 'jsx-pdf';

const SignedGreeting = ({ name }) => {
let greeting;

if (name) {
greeting = ;
} else {
greeting = ;
}

return (
<>
{greeting}

>
);
};

const doc = (





);
```

### Styling

Styling can be done by adding appropriate attributes to tags. It's often helpful for readability to group style-related attributes together and use the spread syntax.

```jsx
import JsxPdf from 'jsx-pdf';

const Greeting = ({ name }) => {
const styles = {
italics: true,
fontSize: 10,
};

return Hello, {name}!;
};

const doc = (





);
```

### Context

Each component has access to global context and can update it if necessary.

```jsx
import JsxPdf from 'jsx-pdf';

const AllowedUsersProvider = (attributes, context, updateContext) => {
updateContext({
allowedUsers: ['Alice'],
});

return attributes.children[0];
};

const SecureGreeting = ({ name }, { allowedUsers }) =>
allowedUsers.includes(name) ? (
Hello, {name}!
) : (
You are not allowed.
);

const doc = (







);
```

## Document primitives

This section describes basic elements provided by the library. More information about supported attributes and advanced examples can be found [here](http://pdfmake.org/playground.html).

### Top elements

Each document has to be enclosed within `document` tag with nested `content`, and optional `header` and `footer`. The document is the place for configuration that affects the whole PDF, such as page margins, page size, default style, and metadata.

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (

Greeting
Hello, Bob!
JSX-PDF, Inc.

);
```

### Dynamic Header and Footer

If you want to use the [dynamic header functionality](https://pdfmake.github.io/docs/document-definition-object/headers-footers/) in pdfmake, simply pass a render function as the only child of the header or footer:

```jsx
const doc = (


{(currentPage, pageCount) => (

Page {currentPage} of {pageCount}.

)}

{/* ... */}

);
```

The parameters are:

- `currentPage` - the 1-indexed page for which the content is being rendered
- `pageCount` - the total number of pages in the document
- `pageSize` - an object containing information about the dimensions of the page.

### Paragraphs

Paragraphs are defined using `text` tag.

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (



This sentence will be rendered as one paragraph,

even though there are

line

breaks.

This is another paragraph.


);
```

In order to apply styling to a group of paragraphs, they can be wrapped with a `stack` tag.

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (



First red paragraph.
Second red paragraph.

Blue parahraph.


);
```

### Columns

Elements nested in `columns` tag will be stacked horizontally.

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (



Fixed width column
Percentage width column

Column that adjusts width based on the content

Column that fills the remaining space



);
```

### Lists

Both ordered and unordered lists are supported.

```jsx
import JsxPdf from 'jsx-pdf';

const docWithOrderedList = (



    Item 1
    Item 2
    Item 3



);

const docWithUnorderedList = (



    Item 1
    Item 2
    Item 3



);
```

### Tables

`table` tag provides a simple way of creating table layouts.

```jsx
const leftCellStyle = {
color: 'grey',
};

const doc = (




Fixed width column
Column that fills the remaining space
Column that adjusts width based on the content


Cell 1.1
Cell 1.2
Cell 1.3


Cell 2.1
Cell 2.2
Cell 2.3




);
```

### Images

`image` supports JPEG and PNG formats.

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (





);
```

### SVGs

The `svg` tag can be used to render SVG images. The `width`, `height` and `fill` attributes can be used to control the size of the image as described in the [pdfmake docs](https://pdfmake.github.io/docs/document-definition-object/svgs/).

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (





`}
/>


);
```

### QR Codes

The `qr` tag can be used to render QR codes. There are various options available as described in the [pdfmake docs](https://pdfmake.github.io/docs/0.1/document-definition-object/qr/).

```jsx
import JsxPdf from 'jsx-pdf';

const doc = (





);
```

## API

### renderPdf

Accepts JSX and returns a PDF JSON representation in the format expected by pdfmake.

### createElement

This function converts JSX to object representation. Every time JSX syntax is used, the function has to be made available. The functionality depends on the babel plugin `@babel/plugin-transform-react-jsx` (or equivalent), and Babel must be set up in the project in order to transpile the JSX correctly.

Example `.babelrc` file:

```json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
],
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{ "pragma": "JsxPdf.createElement", "pragmaFrag": "JsxPdf.Fragment" }
]
]
}
```

## Disclaimer

Copyright 2018 Schibsted

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

## License

By contributing to this project, you agree that your contributions will be licensed under its MIT license.