Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// JavaScript runtime (e.g. Node, the browser, or React Native).
// Here we add the page's to the document. This step is what will cause the
// pages to actually be rendered when the document is opened. Our previous calls
// to `pdfDoc.createPage` only **created** the pages, they did not add them to
// the document.
pdfDoc.insertPage(0, page1).addPage(page3);
// Now we'll convert the `pdfDoc` to a `Uint8Array` containing the bytes of a
// PDF document. This step serializes the document. You can still make changes
// to the document after this step, but you'll have to call `saveToBytes` again
// after doing so.
//
// The `Uint8Array` returned here can be used in a number of ways. What you do
// with it largely depends on the JavaScript environment you're running in.
const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);
/* ========================== 7. Write PDF to File ========================== */
// This step is platform dependent. Since this is a Node script, we can just
// save the `pdfBytes` to the file system, where it can be opened with a PDF
// reader.
const filePath = `${__dirname}/modified.pdf`;
fs.writeFileSync(filePath, pdfBytes);
console.log(`PDF file written to: ${filePath}`);
// JavaScript runtime (e.g. Node, the browser, or React Native).
// Here we add the page's to the document. This step is what will cause the
// pages to actually be rendered when the document is opened. Our previous calls
// to `pdfDoc.createPage` only **created** the pages, they did not add them to
// the document.
pdfDoc.addPage(page1).addPage(page2);
// Now we'll convert the `pdfDoc` to a `Uint8Array` containing the bytes of a
// PDF document. This step serializes the document. You can still make changes
// to the document after this step, but you'll have to call `saveToBytes` again
// after doing so.
//
// The `Uint8Array` returned here can be used in a number of ways. What you do
// with it largely depends on the JavaScript environment you're running in.
const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);
/* ========================== 6. Write PDF to File ========================== */
// This step is platform dependent. Since this is a Node script, we can just
// save the `pdfBytes` to the file system, where it can be opened with a PDF
// reader.
const filePath = `${__dirname}/new.pdf`;
fs.writeFileSync(filePath, pdfBytes);
console.log(`PDF file written to: ${filePath}`);
if (pdfWidth) {
pdfOptions.width = pdfWidth
}
const pdfHeight = doc.getAttributes()['pdf-height']
if (pdfHeight) {
pdfOptions.height = pdfHeight
}
const format = doc.getAttributes()['pdf-format']
if (format) {
pdfOptions.format = format // Paper format. If set, takes priority over width or height options. Defaults to 'Letter'.
}
let pdf = await page.pdf(pdfOptions)
// Outline is not yet implemented in Chromium, so we add it manually here.
// https://bugs.chromium.org/p/chromium/issues/detail?id=840455
let pdfDoc = await PDFDocument.load(pdf)
pdfDoc = await addOutline(pdfDoc, doc)
pdfDoc = await addMetadata(pdfDoc, doc)
pdf = await pdfDoc.save()
if (outputToStdout) {
console.log(pdf.toString())
} else {
fsExtra.writeFileSync(outputFile, pdf)
}
}
} catch (err) {
console.log('Unable to generate the PDF - Error: ' + err.toString())
} finally {
if (watch || preview) {
if (!watch) {
console.log('Preview mode entered, needs to be manually terminated using Ctrl+C!')
await new Promise(resolve => {})
const MARIO_PNG_WIDTH = marioPngDims.width * 0.15;
const MARIO_PNG_HEIGHT = marioPngDims.height * 0.15;
// Here, we define a new "content stream" for the page. A content stream is
// simply a sequence of PDF operators that define what we want to draw on the
// page.
const newContentStream = pdfDoc.createContentStream(
// `drawImage` is a "composite" PDF operator that lets us easily draw an image
// on a page's content stream. "composite" just means that it is composed of
// several lower-level PDF operators. Usually, you'll want to work with
// composite operators - they make things a lot easier! The naming convention
// for composite operators is "draw".
//
// Here we draw the image of Mario on the page's content stream. We'll draw
// him centered horizontally in the top half of the page.
drawImage(MARIO_PNG, {
x: 200,
y: 350,
width: MARIO_PNG_WIDTH,
height: MARIO_PNG_HEIGHT,
}),
// Now let's draw 2 lines of red Courier text near the bottom of the page.
drawLinesOfText(['This text was added', 'with JavaScript!'], {
x: 30,
y: 150,
font: COURIER_FONT,
size: 48,
colorRgb: [1, 0, 0],
}),
);
// Here we (1) register the content stream to the PDF document, and (2) add the
const TEXT_BOX_WIDTH = 295;
// Let's define some RGB colors. Note that these arrays are of the form:
// [, , ]
// where each color value must be in the range 0.0-1.0. Note that they should
// *not* be in the range 0-255 as they would be if you were writing CSS styles.
const SOLARIZED_WHITE = [253 / 255, 246 / 255, 227 / 255];
const SOLARIZED_GRAY = [101 / 255, 123 / 255, 131 / 255];
// Here, we define the second page's "content stream". A content stream is
// simply a sequence of PDF operators that define what we want to draw on the
// page.
const contentStream2 = pdfDoc.createContentStream(
// Here we draw the image of Mario on the page's content stream. We'll draw
// him centered horizontally in the top half of the page.
drawImage(MARIO_PNG, {
x: PAGE_2_WIDTH * 0.5 - MARIO_PNG_WIDTH * 0.5,
y: PAGE_2_HEIGHT * 0.5,
width: MARIO_PNG_WIDTH,
height: MARIO_PNG_HEIGHT,
}),
// Next we'll draw a Solarized White rectangle with a Solarized Gray border
// beneath the image of Mario. It will be centered horizontally in the page.
drawRectangle({
x: PAGE_2_WIDTH * 0.5 - TEXT_BOX_WIDTH * 0.5,
y: PAGE_2_HEIGHT * 0.5 - 100,
width: TEXT_BOX_WIDTH,
height: 90,
colorRgb: SOLARIZED_WHITE,
borderWidth: 4,
borderColorRgb: SOLARIZED_GRAY,
}),
drawText('This PDF was Created with JavaScript!', {
x: 85,
y: PAGE_1_HEIGHT - 48,
font: HELVETIVA_FONT,
size: 24,
}),
drawText(helveticaFont.encodeText('Olé! - Œ'), {
x: PAGE_1_WIDTH * 0.5 - 30,
y: PAGE_1_HEIGHT - 48 - 30,
font: HELVETIVA_FONT,
size: 12,
}),
// Now we'll draw the Unicorn image on the page's content stream. We'll
// position it a little bit below the text we just drew, and we'll center it
// within the page.
drawImage(UNICORN_JPG, {
x: PAGE_1_WIDTH * 0.5 - UNICORN_JPG_WIDTH * 0.5,
y: PAGE_1_HEIGHT * 0.5,
width: UNICORN_JPG_WIDTH,
height: UNICORN_JPG_HEIGHT,
}),
// Finally, let's draw an ellipse on the page's content stream. We'll draw it
// below the image we just drew, and we'll center it within the page. We'll
// color it cyan, with a purple border.
drawEllipse({
x: PAGE_1_WIDTH * 0.5,
y: PAGE_1_HEIGHT * 0.2,
xScale: 150,
yScale: 50,
borderWidth: 15,
colorRgb: CYAN,
borderColorRgb: PURPLE,
height: MARIO_PNG_HEIGHT,
}),
// Next we'll draw a Solarized White rectangle with a Solarized Gray border
// beneath the image of Mario. It will be centered horizontally in the page.
drawRectangle({
x: PAGE_2_WIDTH * 0.5 - TEXT_BOX_WIDTH * 0.5,
y: PAGE_2_HEIGHT * 0.5 - 100,
width: TEXT_BOX_WIDTH,
height: 90,
colorRgb: SOLARIZED_WHITE,
borderWidth: 4,
borderColorRgb: SOLARIZED_GRAY,
}),
// Now we'll draw three lines of text within the rectangle we just drew. The
// text will be drawn in the Ubuntu font colored Solarized Gray.
drawLinesOfText(
[
'Here is a picture of Mario',
'running. It was placed in',
'this PDF using JavaScript!',
],
{
x: PAGE_2_WIDTH * 0.5 - TEXT_BOX_WIDTH * 0.5 + 10,
y: PAGE_2_HEIGHT * 0.5 - 38,
font: UBUNTU_FONT,
size: 24,
colorRgb: SOLARIZED_GRAY,
},
),
);
// Here we (1) register the content stream to the PDF document, and (2) add the
// `drawImage` is a "composite" PDF operator that lets us easily draw an image
// on a page's content stream. "composite" just means that it is composed of
// several lower-level PDF operators. Usually, you'll want to work with
// composite operators - they make things a lot easier! The naming convention
// for composite operators is "draw".
//
// Here we draw the image of Mario on the page's content stream. We'll draw
// him centered horizontally in the top half of the page.
drawImage(MARIO_PNG, {
x: 200,
y: 350,
width: MARIO_PNG_WIDTH,
height: MARIO_PNG_HEIGHT,
}),
// Now let's draw 2 lines of red Courier text near the bottom of the page.
drawLinesOfText(['This text was added', 'with JavaScript!'], {
x: 30,
y: 150,
font: COURIER_FONT,
size: 48,
colorRgb: [1, 0, 0],
}),
);
// Here we (1) register the content stream to the PDF document, and (2) add the
// reference to the registered stream to the page's content streams.
existingPage.addContentStreams(pdfDoc.register(newContentStream));
/* ================= 4. Setup and Create New First Page ===================== */
// This step is platform independent. The same code can be used in any
// JavaScript runtime (e.g. Node, the browser, or React Native).
const page1 = pdfDoc
// Here, we define the second page's "content stream". A content stream is
// simply a sequence of PDF operators that define what we want to draw on the
// page.
const contentStream2 = pdfDoc.createContentStream(
// Here we draw the image of Mario on the page's content stream. We'll draw
// him centered horizontally in the top half of the page.
drawImage(MARIO_PNG, {
x: PAGE_2_WIDTH * 0.5 - MARIO_PNG_WIDTH * 0.5,
y: PAGE_2_HEIGHT * 0.5,
width: MARIO_PNG_WIDTH,
height: MARIO_PNG_HEIGHT,
}),
// Next we'll draw a Solarized White rectangle with a Solarized Gray border
// beneath the image of Mario. It will be centered horizontally in the page.
drawRectangle({
x: PAGE_2_WIDTH * 0.5 - TEXT_BOX_WIDTH * 0.5,
y: PAGE_2_HEIGHT * 0.5 - 100,
width: TEXT_BOX_WIDTH,
height: 90,
colorRgb: SOLARIZED_WHITE,
borderWidth: 4,
borderColorRgb: SOLARIZED_GRAY,
}),
// Now we'll draw three lines of text within the rectangle we just drew. The
// text will be drawn in the Ubuntu font colored Solarized Gray.
drawLinesOfText(
[
'Here is a picture of Mario',
'running. It was placed in',
'this PDF using JavaScript!',
],
// This step is platform independent. The same code can be used in any
// JavaScript runtime (e.g. Node, the browser, or React Native).
const page1 = pdfDoc
.createPage([600, 250])
.addFontDictionary(UBUNTU_FONT, ubuntuFontRef);
// Let's define some RGB colors. Note that these arrays are of the form:
// [, , ]
// where each color value must be in the range 0.0-1.0. Note that they should
// *not* be in the range 0-255 as they would be if you were writing CSS styles,
// which is why we are dividing each color component by 255.
const PURPLE = [119 / 255, 41 / 255, 83 / 255];
const ORANGE = [224 / 255, 90 / 255, 43 / 255];
const contentStream1 = pdfDoc.createContentStream(
drawRectangle({
width: 600,
height: 250,
colorRgb: PURPLE,
}),
drawLinesOfText(
['This is the new first page.', 'It was inserted with JavaScript!'],
{
x: 30,
y: 130,
font: UBUNTU_FONT,
size: 38,
colorRgb: ORANGE,
},
),
);