Implement printing to PDF
This patch implements: - puppeteer's Page.printToPDF method. The method's defaults are similar to phantom's defaults for the paperSize property. - phantom's render into pdf file.
This commit is contained in:
parent
72ce46c4f6
commit
91e54378a3
101
lib/Page.js
101
lib/Page.js
@ -386,6 +386,54 @@ class Page extends EventEmitter {
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {!Object=} options
|
||||
*/
|
||||
async printToPDF(filePath, options) {
|
||||
options = options || {};
|
||||
|
||||
var scale = options.scale || 1;
|
||||
var displayHeaderFooter = options.displayHeaderFooter || false;
|
||||
var printBackground = options.printBackground || true;
|
||||
var landscape = options.landscape || false;
|
||||
var pageRanges = options.pageRanges || '';
|
||||
|
||||
var paperWidth = 8.5;
|
||||
var paperHeight = 11;
|
||||
if (options.format) {
|
||||
var format = Page.PaperFormats[options.format];
|
||||
console.assert(format, 'Unknown paper format: ' + options.format);
|
||||
paperWidth = format.width;
|
||||
paperHeight = format.height;
|
||||
} else {
|
||||
paperWidth = convertPrintParameterToInches(options.width) || paperWidth;
|
||||
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
|
||||
}
|
||||
|
||||
var marginOptions = options.margin || {};
|
||||
var marginTop = convertPrintParameterToInches(marginOptions.top) || 0;
|
||||
var marginLeft = convertPrintParameterToInches(marginOptions.left) || 0;
|
||||
var marginBottom = convertPrintParameterToInches(marginOptions.bottom) || 0;
|
||||
var marginRight = convertPrintParameterToInches(marginOptions.right) || 0;
|
||||
|
||||
var result = await this._client.send('Page.printToPDF', {
|
||||
landscape: landscape,
|
||||
displayHeaderFooter: displayHeaderFooter,
|
||||
printBackground: printBackground,
|
||||
scale: scale,
|
||||
paperWidth: paperWidth,
|
||||
paperHeight: paperHeight,
|
||||
marginTop: marginTop,
|
||||
marginBottom: marginBottom,
|
||||
marginLeft: marginLeft,
|
||||
marginRight: marginRight,
|
||||
pageRanges: pageRanges
|
||||
});
|
||||
var buffer = new Buffer(result.data, 'base64');
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
@ -429,6 +477,59 @@ Page.ScreenshotTypes = {
|
||||
JPG: "jpeg",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
Page.PaperFormats = {
|
||||
Letter: {width: 8.5, height: 11},
|
||||
Legal: {width: 8.5, height: 14},
|
||||
Tabloid: {width: 11, height: 17},
|
||||
Ledger: {width: 17, height: 11},
|
||||
A0: {width: 33.1, height: 46.8 },
|
||||
A1: {width: 23.4, height: 33.1 },
|
||||
A2: {width: 16.5, height: 23.4 },
|
||||
A3: {width: 11.7, height: 16.5 },
|
||||
A4: {width: 8.27, height: 11.7 },
|
||||
A5: {width: 5.83, height: 8.27 },
|
||||
};
|
||||
|
||||
var unitToPixels = {
|
||||
'px': 1,
|
||||
'in': 96,
|
||||
'cm': 37.8,
|
||||
'mm': 3.78
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {(string|number|undefined)} parameter
|
||||
* @return {(number|undefined)}
|
||||
*/
|
||||
function convertPrintParameterToInches(parameter) {
|
||||
if (typeof parameter === 'undefined')
|
||||
return undefined;
|
||||
var pixels;
|
||||
if (typeof parameter === 'number') {
|
||||
// Treat numbers as pixel values to be aligned with phantom's paperSize.
|
||||
pixels = /** @type {number} */ (parameter);
|
||||
} else if (typeof parameter === 'string') {
|
||||
var text = parameter;
|
||||
var unit = text.substring(text.length - 2).toLowerCase();
|
||||
var valueText = '';
|
||||
if (unitToPixels.hasOwnProperty(unit)) {
|
||||
valueText = text.substring(0, text.length - 2);
|
||||
} else {
|
||||
// In case of unknown unit try to parse the whole parameter as number of pixels.
|
||||
// This is consistent with phantom's paperSize behavior.
|
||||
unit = 'px';
|
||||
valueText = text;
|
||||
}
|
||||
var value = Number(valueText);
|
||||
console.assert(!isNaN(value), 'Failed to parse parameter value: ' + text);
|
||||
var pixels = value * unitToPixels[unit];
|
||||
} else {
|
||||
throw new Error('printToPDF Cannot handle parameter type: ' + (typeof parameter));
|
||||
}
|
||||
return pixels / 96;
|
||||
};
|
||||
|
||||
Page.Events = {
|
||||
Alert: 'alert',
|
||||
BeforeUnload: 'beforeunload',
|
||||
|
@ -276,7 +276,18 @@ class WebPage {
|
||||
height: this.clipRect.height
|
||||
};
|
||||
}
|
||||
var imageBuffer = await(this._page.saveScreenshot(fileName, clipRect));
|
||||
if (fileName.endsWith('pdf')) {
|
||||
var options = {};
|
||||
var paperSize = this.paperSize || {};
|
||||
options.margin = paperSize.margin;
|
||||
options.format = paperSize.format;
|
||||
options.landscape = paperSize.orientation === 'landscape';
|
||||
options.width = paperSize.width;
|
||||
options.height = paperSize.height;
|
||||
await(this._page.printToPDF(fileName, options));
|
||||
} else {
|
||||
await(this._page.saveScreenshot(fileName, clipRect));
|
||||
}
|
||||
}
|
||||
|
||||
release() {
|
||||
|
Loading…
Reference in New Issue
Block a user