Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Puppeteer - How to change orientation of some pages in a document?

I'm using Puppeteer to create a 30-page long pdf and a few of the pages need to be landscape orientated. How can I specify it only for page x and page y ?

like image 377
Victor Avatar asked Mar 02 '19 09:03

Victor


People also ask

How to change page orientation to landscape in Word document?

Step 1: Click Page Layout, and go to the Breaks to insert section break Next Page in Section Breaks section at the end of page 1 and page 2 as follows. Step 2: Put the cursor on page 2 and click Page Layout > Orientation > Landscape. Now the page 2 has been changed to orientation landscape. See screenshot:

Is it better to know the page orientation before creating a document?

If you know the page orientation for your document from the beginning, it is better to apply it before you create the content. Your design decisions (such as font size and placement of images) are likely to change based on the page orientation you choose.

How do I set the orientation of a section in word?

Let Word Insert Section Breaks and Set the Orientation. Click the Layout tab. In the Page Setup section, open the Page Setup details window by clicking the small arrow located in the lower right corner of the section. Click the Margins tab. In the Orientation section, select Portrait or Landscape. At the bottom of the window,...

How to change the orientation of one page in margins?

Change orientation of one page in Margins. 1: Select the entire page that you want to change the orientation, then click Page Layout> Margins and select Custom Margins. 2: In the Page Setup window, select the orientation you need in Oriention section, and choose Selected text in Apply to. Click OK. Note: 1.


2 Answers

Pseudo Selectors for @page

According to the documentation or CSS spec, you can set up different orientation to some pages using CSS.

@page :pseudo-selector{
 size: landscape;
}

The acceptable and working pseudo-selectors (that I tested with puppeteer and google chrome) includes,

:blank
:first
:left
:right

Result: enter image description here

PS: At the moment of answer, other selectors like :nth-child and page identifies mentioned on the draft does not work on chrome version 73.

Alternative way

The only other way to deal with this is to print pages separately and then merge them later on. You can print specific pages with pageRanges,

page.pdf({pageRanges: '1-5', path: 'first.pdf'})

And use packages like pdf-merge to merge two pdf file.

const PDFMerge = require('pdf-merge');
PDFMerge(['first.pdf', 'second.pdf'], {output: `${__dirname}/3.pdf`})
like image 164
Md. Abu Taher Avatar answered Oct 25 '22 18:10

Md. Abu Taher


Well, according to caniuse, you can use the page property with Chrome 85 and up

So you can use @page followed by a "named page name" in combination with the page property to set a different orientation (or any other properties) to any page you want.

example:

@page rotated {
   size: landscape;
}

.rotated_class {
   page: rotated;
}

Page example, just right click -> print to see it in action

EDIT

Well, after writing this solution I found a major problem with the @page approach. If you try to print the example page I linked to just above, you'll see that the viewport of the rotated pages is limited to the width of the first page if the first page is in portrait (and limited in height if the first page is in landscape).

The solution I ended up using for the page rotation is a bit whack and needs a second library, but it works :

  • Set a different size on the pages you want to be rotated (here I change it by 0.1 inch which is about 1 pixel in the end) and assign it to your corresponding pages
    @page rotated {
       size: 8.49in 11in;
    }

    .rotated_class {
       page: rotated;
    }
  • I use pdf-lib after the puppeteer generation to open the pdf and rotate every page smaller than a normal page (in my case I check if the width is smaller than 612 pixels)
  const pages = pdf.getPages();
  for (let i = 0; i < pages.length; ++i) {
    const pageToRotate = pages[i];
    if (pageToRotate.getWidth() < 612) {
      pageToRotate.setRotation(degrees(-90));
    }
  }
  pdfBuffer = Buffer.from(await pdf.save());

  • the Page size is the only info I found that could be "transferred" from the css to the pdf-lib to flag any page to be rotated, hence why I'm using that solution.

Hopefully the "viewport bug" will be fixed in the future and we'll be able to use the @page landscape/portrait property

like image 43
Max Lemieux Avatar answered Oct 25 '22 19:10

Max Lemieux