Skip to content
This repository has been archived by the owner on Dec 6, 2022. It is now read-only.

Commit

Permalink
Merge pull request #11 from PredicSis/tp-puppeteer
Browse files Browse the repository at this point in the history
[master] Move from PhantomJS to Puppeteer
  • Loading branch information
bmurzeau committed Jan 12, 2018
2 parents c73f291 + 965803e commit 3bdfb03
Show file tree
Hide file tree
Showing 7 changed files with 2,739 additions and 132 deletions.
10 changes: 6 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
FROM mhart/alpine-node:5.10
MAINTAINER Gregoire MORPAIN <gm@predicsis.com>
FROM node:8
MAINTAINER Gregoire MORPAIN <gm@predicsis.com>, mdouchement

ENV NODE_ENV production
ENV DOCKER_EXECUTION 1

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ARG chromium_libs='gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils'
RUN apt-get update && apt-get install -y git ${chromium_libs} --no-install-recommends && rm -rf /var/lib/apt/lists/*

COPY package.json /usr/src/app/
RUN apk update && apk add git
RUN curl -Ls "https://github.com/dustinblackman/phantomized/releases/download/2.1.1/dockerized-phantomjs.tar.gz" | tar xz -C /
RUN npm install
COPY . /usr/src/app/

Expand Down
19 changes: 5 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
# html2pdf

PDF screenshot API based on PhantomJS
PDF screenshot API based on Puppeteer.

##### Node version
version >= `4.0.0`
version >= `8.0.0`

## Usage

```bash
$ NODE_ENV=production npm install
$ NODE_ENV=production PORT=4005 npm start
```

```
Open http://localhost:4005/export?url=http://www.google.com&filename=google.pdf&format=A4&orientation=portrait
$ DEBUG=1 NODE_ENV=production PORT=4005 npm start
```

### Usage with SPA

```js
// on page_load
window.phantomWaitForCallback = true;

// when you are done fetching your api and rendering the page
if (typeof window.callPhantom === 'function') {
window.callPhantom({ event: 'loaded' });
}
```
Open http://localhost:4005/export?url=http://www.google.com&filename=google.pdf&format=A4&orientation=portrait
```
121 changes: 101 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,107 @@
var express = require('express');
var generatePDF = require('./pdf/export');
var express = require('express')
var fs = require('fs')
var tmp = require('tmp')
const puppeteer = require('puppeteer')

var app = express();
app.set('port', process.env.PORT || 4005);
// Global
var debug = (process.env.DEBUG === '1')
tmp.setGracefulCleanup()

app.get('/export', function (req, res) {
console.log('generating pdf with params :', req.query);
var browserOpts = {}
if (process.env.DOCKER_EXECUTION === '1') {
browserOpts = {
executablePath: process.env.CHROMIUM_BIN,
args: ['--no-sandbox', '--headless', '--disable-gpu', '--disable-dev-shm-usage']
}
}

// PDF

async function _generatePDF(url, orientation, format, tmpFile) {
const browser = await puppeteer.launch(browserOpts)
try {
const page = await browser.newPage()

// From the launched Chromium console. Useful for debug.
if (debug) {
page.on('console', msg => {
console.log('--CONSOLE------------------')
for (let i = 0; i < msg.args.length; ++i)
console.log(`${i}: ${msg.args[i]}`)
console.log('___________________________')
})
}

page.on('pageerror', errmsg => {
console.log('[pageerror] ' + errmsg)

throw new Error(errmsg)
})

page.on('error', err => {
console.log('[ERROR] ' + err.message)
console.log(err.stack)

throw err
})

await page.goto(url, {waitUntil: 'networkidle2'})
await new Promise(resolve => setTimeout(resolve, 1000)) // wait for CSS animations

// https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagepdfoptions
await page.pdf({
path: tmpFile,
format: format,
landscape: orientation === 'landscape'
})
} finally {
browser.close()
}
}

var generatePDF = (url, orientation, format) => {
return new Promise((resolve, reject) => {
tmp.file((err, tmpFile) => {
if (err) {
return reject(err)
}

_generatePDF(url, orientation, format, tmpFile)
.then((data) => {
fs.access(tmpFile, fs.F_OK, (err) => {
if (err) {
return reject(err)
}
return resolve(fs.createReadStream(tmpFile))
})
})
.catch(err => reject(err))
})
})
}

// Server

var app = express()
app.set('port', process.env.PORT || 4005)

app.get('/export', (req, res) => {
console.log('generating pdf with params :', req.query)
if (!req.query || !req.query.url) {
return res.status(404).end('missing url param');
return res.status(404).end('missing url param')
}
generatePDF(req.query.url, req.query.orientation, req.query.format)
.then(function(stream) {
res.attachment(req.query.filename);
stream.pipe(res);
console.log('generated pdf with params :');
console.log(req.query);
.then(stream => {
res.attachment(req.query.filename)
stream.pipe(res)
console.log('generated pdf with params :')
console.log(req.query)
})
.catch(function(err) {
console.error(err);
res.status(500).json(err);
});
});

app.listen(app.get('port'));
console.info('listening on port: ' + app.get('port'));
.catch(err => {
console.error(err)
res.status(500).json(err)
})
})

app.listen(app.get('port'))
console.info('listening on port: ' + app.get('port'))

0 comments on commit 3bdfb03

Please sign in to comment.