├── .eslintrc
├── .gitignore
├── README.md
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
└── webpack.config.generate.js
├── example
└── invoice.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── scripts
├── build.js
├── start.js
└── test.js
├── server
├── createPDF.js
└── template.html
└── src
├── Invoice.css
├── Invoice.js
├── elements
├── Address
│ ├── Address.css
│ ├── Address.js
│ └── Block.js
├── Header
│ ├── Header.css
│ ├── Header.js
│ └── logo.png
└── List
│ ├── List.css
│ └── List.js
├── global.css
├── index.js
└── vendor
└── normalize.css
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "react-app"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # generated output
10 | /build
11 |
12 | # compiled files
13 | /lib
14 |
15 | # ignore the yarn lockfile as this is a demo repository
16 | yarn.lock
17 |
18 | # misc
19 | .DS_Store
20 | .env
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This project is no longer being maintained
2 |
3 |
4 | ---
5 | # Generating PDFs with React
6 | This is an example project you can use to generate PDFs with React. Start by checking the related talk slides [here](http://bit.ly/react-emails-pdf).
7 |
8 | > If you want to generate emails using React, check the [react-emails](https://github.com/lang-ai/react-emails) repo.
9 |
10 | ### Example
11 |
12 | To provide an example as starting point, this project generates a demo invoice.
13 |
14 | To generate the example:
15 |
16 | ```
17 | $ npm install
18 | $ npm run build
19 | $ node example/invoice.js
20 | ```
21 |
22 | The result PDF will be saved in the `/build/` directory. Here is how it looks like:
23 |
24 | 
25 |
26 |
27 | ### Development
28 |
29 | This project was bootstrapped with [Create React App][react-create-app].
30 | See the development guide [here][react-create-app-guide].
31 |
32 |
33 | ### Creating the PDF
34 |
35 | To create the PDF, simply import the function (you may want to use it as a module) and call it with the
36 | data. It returns a promise that resolves when the generated PDF path.
37 |
38 | ```js
39 | // In case you use it as a module
40 | // const createPDF = require('react-pdfs-example');
41 |
42 | const createPDF = require('../server/createPDF');
43 |
44 | const data = {
45 | date: new Date().toISOString(),
46 | number: 32149,
47 | recipient: {
48 | displayName: 'John White',
49 | addressLine: 'CEO at Carddesign.con\nLondon, United Kingdom',
50 | },
51 | // more data...
52 | };
53 |
54 | createPDF(data)
55 | .then((path) => {
56 | // PDF has been generated with the config from the function
57 | // generatePDF() inside server/createPDF.js.
58 | // Returns the generated PDF path.
59 | });
60 | ```
61 |
62 | - - - - - - - - - -
63 |
64 | [][langai]
65 |
66 | **Built with ❤️ by Lang.ai**
67 |
68 | [langai]: https://building.lang.ai/
69 | [react-create-app]: https://github.com/facebookincubator/create-react-app
70 | [react-create-app-guide]: https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md
71 |
72 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
4 | // injected into the application via DefinePlugin in Webpack configuration.
5 |
6 | var REACT_APP = /^REACT_APP_/i;
7 |
8 | function getClientEnvironment(publicUrl) {
9 | var raw = Object
10 | .keys(process.env)
11 | .filter(key => REACT_APP.test(key))
12 | .reduce((env, key) => {
13 | env[key] = process.env[key];
14 | return env;
15 | }, {
16 | // Useful for determining whether we’re running in production mode.
17 | // Most importantly, it switches React into the correct mode.
18 | 'NODE_ENV': process.env.NODE_ENV || 'development',
19 | // Useful for resolving the correct path to static assets in `public`.
20 | // For example,
.
21 | // This should only be used as an escape hatch. Normally you would put
22 | // images into the `src` and `import` them in code to get their paths.
23 | 'PUBLIC_URL': publicUrl
24 | });
25 | // Stringify all values so we can feed into Webpack DefinePlugin
26 | var stringified = {
27 | 'process.env': Object
28 | .keys(raw)
29 | .reduce((env, key) => {
30 | env[key] = JSON.stringify(raw[key]);
31 | return env;
32 | }, {})
33 | };
34 |
35 | return { raw, stringified };
36 | }
37 |
38 | module.exports = getClientEnvironment;
39 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var path = require('path');
4 | var fs = require('fs');
5 | var url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | var appDirectory = fs.realpathSync(process.cwd());
10 | function resolveApp(relativePath) {
11 | return path.resolve(appDirectory, relativePath);
12 | }
13 |
14 | // We support resolving modules according to `NODE_PATH`.
15 | // This lets you use absolute paths in imports inside large monorepos:
16 | // https://github.com/facebookincubator/create-react-app/issues/253.
17 |
18 | // It works similar to `NODE_PATH` in Node itself:
19 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
20 |
21 | // We will export `nodePaths` as an array of absolute paths.
22 | // It will then be used by Webpack configs.
23 | // Jest doesn’t need this because it already handles `NODE_PATH` out of the box.
24 |
25 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
26 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
27 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
28 |
29 | var nodePaths = (process.env.NODE_PATH || '')
30 | .split(process.platform === 'win32' ? ';' : ':')
31 | .filter(Boolean)
32 | .filter(folder => !path.isAbsolute(folder))
33 | .map(resolveApp);
34 |
35 | var envPublicUrl = process.env.PUBLIC_URL;
36 |
37 | function ensureSlash(path, needsSlash) {
38 | var hasSlash = path.endsWith('/');
39 | if (hasSlash && !needsSlash) {
40 | return path.substr(path, path.length - 1);
41 | } else if (!hasSlash && needsSlash) {
42 | return path + '/';
43 | } else {
44 | return path;
45 | }
46 | }
47 |
48 | function getPublicUrl(appPackageJson) {
49 | return envPublicUrl || require(appPackageJson).homepage;
50 | }
51 |
52 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
53 | // "public path" at which the app is served.
54 | // Webpack needs to know it to put the right