Skip to content

Instantly share code, notes, and snippets.

@marcj
Last active October 2, 2020 14:41
Show Gist options
  • Save marcj/463775beb6f4def97025f6a788d4d4ec to your computer and use it in GitHub Desktop.
Save marcj/463775beb6f4def97025f6a788d4d4ec to your computer and use it in GitHub Desktop.
Render Angular as PDF in Puppeteer
//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