├── .gitignore
├── .npmignore
├── README.md
├── bin
├── phantomjs-linux
└── phantomjs-mac
├── event.json
├── example
└── example.html
├── handler.js
├── lib
└── rasterize.js
├── package.json
└── serverless.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # package directories
2 | node_modules
3 | jspm_packages
4 |
5 | # Serverless directories
6 | .serverless
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | serverless-html-pdf
2 | ===================
3 |
4 | This lambda function takes a HTML page and convert it into printable PDF using PhantomJS and the rasterize script packaged in the PhantomJS examples.
5 |
6 | ### Setup
7 |
8 | For deployment
9 | ```
10 | sls deploy
11 | ```
12 |
--------------------------------------------------------------------------------
/bin/phantomjs-linux:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvintychan/serverless-html-pdf/37528562fbf29134ab7bea7d29c0bcd686c25053/bin/phantomjs-linux
--------------------------------------------------------------------------------
/bin/phantomjs-mac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvintychan/serverless-html-pdf/37528562fbf29134ab7bea7d29c0bcd686c25053/bin/phantomjs-mac
--------------------------------------------------------------------------------
/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": {
3 | "url": "https://www.google.com/"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/example/example.html:
--------------------------------------------------------------------------------
1 | !
2 |
3 |
4 | Convert HTML to PDF Example
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/handler.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const execFile = require('child_process').execFile;
6 |
7 | module.exports.print = (event, context, callback) => {
8 | console.log(event);
9 | const body = JSON.parse(event.body);
10 | const phantomjs = path.resolve('bin/phantomjs-linux');
11 | const rasterize = path.resolve('lib/rasterize.js');
12 | const outputPDF = '/tmp/output.pdf';
13 | const url = body.url;
14 |
15 | if (!url) {
16 | const err = 'url parameter is undefined';
17 | return callback(err, {
18 | statusCode: 500,
19 | body: JSON.stringify({ 'error': err })
20 | });
21 | }
22 |
23 | execFile(phantomjs, [rasterize, url, outputPDF, "A4", 0.68], (err, stdout, stderr) => {
24 | console.log('execute phantomjs');
25 | if (err) {
26 | console.log(err);
27 | callback(err, {
28 | statusCode: 500,
29 | body: JSON.stringify({
30 | 'error': err
31 | }),
32 | });
33 | }
34 | const output = fs.readFileSync(outputPDF);
35 | callback(null, {
36 | statusCode: 200,
37 | headers: {
38 | 'Access-Control-Allow-Origin': '*',
39 | },
40 | body: output.toString('base64')
41 | });
42 | });
43 |
44 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration
45 | // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
46 | };
47 |
--------------------------------------------------------------------------------
/lib/rasterize.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var page = require('webpage').create(),
3 | system = require('system'),
4 | address, output, size, pageWidth, pageHeight;
5 |
6 | if (system.args.length < 3 || system.args.length > 5) {
7 | console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
8 | console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
9 | console.log(' image (png/jpg output) examples: "1920px" entire page, window width 1920px');
10 | console.log(' "800px*600px" window, clipped to 800x600');
11 | phantom.exit(1);
12 | } else {
13 | address = system.args[1];
14 | output = system.args[2];
15 | page.viewportSize = { width: 600, height: 600 };
16 | if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
17 | size = system.args[3].split('*');
18 | page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
19 | : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
20 | } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
21 | size = system.args[3].split('*');
22 | if (size.length === 2) {
23 | var pageWidth = parseInt(size[0], 10),
24 | pageHeight = parseInt(size[1], 10);
25 | page.viewportSize = { width: pageWidth, height: pageHeight };
26 | page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
27 | } else {
28 | console.log("size:", system.args[3]);
29 | var pageWidth = parseInt(system.args[3], 10),
30 | pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
31 | console.log ("pageHeight:",pageHeight);
32 | page.viewportSize = { width: pageWidth, height: pageHeight };
33 | }
34 | }
35 | if (system.args.length > 4) {
36 | page.zoomFactor = system.args[4];
37 | }
38 | page.open(address, function (status) {
39 | if (status !== 'success') {
40 | console.log('Unable to load the address!');
41 | phantom.exit(1);
42 | } else {
43 | window.setTimeout(function () {
44 | page.render(output);
45 | phantom.exit();
46 | }, 200);
47 | }
48 | });
49 | }
50 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "serverless-pdf",
3 | "version": "1.0.0",
4 | "description": "Convert HTML to PDF thru a lambda function using phantomjs and rasterize.",
5 | "main": "handler.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "serverless",
11 | "pdf"
12 | ],
13 | "author": "Calvin Chan ",
14 | "license": "MIT",
15 | "devDependencies": {
16 | "aws-sdk": "^2.20.0"
17 | },
18 | "dependencies": {
19 | "mocha": "^3.2.0",
20 | "serverless-webpack": "^1.0.0-rc.4",
21 | "webpack": "^1.13.3"
22 | },
23 | "browser": {
24 | "vertx": false
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/serverless.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Serverless!
2 | #
3 | # This file is the main config file for your service.
4 | # It's very minimal at this point and uses default values.
5 | # You can always add more config options for more control.
6 | # We've included some commented out config examples here.
7 | # Just uncomment any of them to get that config option.
8 | #
9 | # For full config options, check the docs:
10 | # docs.serverless.com
11 | #
12 | # Happy Coding!
13 |
14 | service: serverless-pdf
15 |
16 | provider:
17 | name: aws
18 | runtime: nodejs4.3
19 | stage: stage
20 | region: us-west-2
21 | profile: serverless
22 |
23 | functions:
24 | print:
25 | handler: handler.print
26 | events:
27 | - http:
28 | method: post
29 | path: print
30 | cors: true
31 |
32 | # plugins:
33 | # - serverless-webpack
34 |
35 | package:
36 | exclude:
37 | - node_modules/**
38 | - bin/**
39 | include:
40 | - bin/phantomjs-linux
41 | - lib/rasterize.js
42 |
--------------------------------------------------------------------------------