Last active
October 2, 2020 14:41
-
-
Save marcj/463775beb6f4def97025f6a788d4d4ec to your computer and use it in GitHub Desktop.
Render Angular as PDF in Puppeteer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//this is more or less pseudocode, not tested, just to demonstrate how it could look like conceptually. | |
import {AppServerModule} from './src/main.server'; | |
import {ngExpressEngine} from '@nguniversal/express-engine'; | |
const puppeteer = require('puppeteer'); | |
const {join} = require('path'); | |
const {readFileSync} = require('fs'); | |
async function main() { | |
const renderer = ngExpressEngine({ | |
bootstrap: AppServerModule, | |
}); | |
//1. first generate HTML of Angular app | |
const html = await new Promise<string>((resolve, reject) => { | |
renderer('/', { | |
//you can inject here custom data to the DI container | |
//so that you can load certain stuff. You can however use also the | |
//url to inject data via query parameters which you need then to read from the Agnular Router. | |
providers: [{provide: 'CUSTOMER_IDWHATEVER', useValue: 213123}] | |
}, | |
(error, html) => { | |
if (error) reject(error) | |
else resolve(html); | |
}) | |
; | |
}); | |
//2. generated HTML contains asset links, like css/scripts/images. Intercept and load from disc directly | |
const assetFilePath = join(__dirname, "./assets/index.html"); | |
page.on("request", interceptedRequest => { | |
const url = interceptedRequest.url(); | |
if (url.startsWith("file://") && !url.match(assetFilePath)) { | |
interceptedRequest.respond({ | |
body: readFileSync( | |
join(__dirname, "./assets/", url.replace("file://", "")) | |
) | |
}); | |
} else { | |
interceptedRequest.continue(); | |
} | |
}); | |
//3. start headless chrome | |
const browser = await puppeteer.launch({ | |
executablePath: '/usr/bin/chromium-browser', | |
args: ['--no-sandbox', '--headless', '--disable-gpu'] | |
}); | |
const page = await browser.newPage(); | |
await page.setContent(html); | |
//4. render actual PDF | |
const pdf = await page.pdf({format: 'A3'}); | |
//pdf is a node Buffer now. Send to client, store as file, or whatever. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment