Electron js webContents.print options not working (always prints on A4 page)

Viewed 1597

I'm working on a cinema ticketing application and when I print ticket it always prints on A4 page. I need the ticket on the small page not on a full-size a4 page. I tried to fix this by using CSS but the results are always the same for page size.

HTML Template

data:text/html;charset=utf-8,
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
   <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
   <title>Print Ticket</title>
   <style type="text/css">
   </style>
</head>
<body>
   <div>
      <div style="width: 471px; height: 431px; padding-left: 20px; border-radius: 10px 10px 0 0; font-family: Helvetica; display: flex">
         <div style="  width: 470px;">
            <div style="display: flex;">
               <div style="height: 80px">
                  <h1 style="border-bottom: 6px rgb(147, 47, 60) solid;">YABOUS TICKET</h1>
               </div>
            </div>
            <div style="width: 470px; display: flex;">
               <div style="max-width: 280px">
                  <div style="width: 310px; height: 70px; display: flex; justify-content: space-between;">
                     <div style="width:240px"> <span style="font-weight: 550; font-size: 20px">EVENT</span>
                        <br> <span style="font-size: 20px">%event%</span> 
                     </div>
                  </div>
                  <div style="height: 70px; max-width: 290px"> 
                     <span style="font-weight: 550; font-size: 20px">HALL</span>
                     <br> <span style="font-size: 20px">%hall%</span> 
                  </div>
                  <div style="height: 70px"> <span style="font-weight: 550; font-size: 20px">TICKET NO.</span><span style="font-weight: 550; font-size: 20px; margin-left: 90px;">PRICE</span>
                     <br> <span style="font-size: 20px">%seatNo%</span> <span style="font-size: 20px; margin-right: 35px; float: right">%ticketPrice%</span> 
                  </div>
                  <div style="height: 90px; display: flex; align-items: flex-end">
                     <div style="width: 80px; height: 70px"> <span style="font-weight: 550; font-size: 15px">FLOOR</span>
                        <br> <span style="color: rgb(69, 68, 67); font-size: 25px"><b>%floor%</b></span> 
                     </div>
                     <div style="width: 80px; height: 70px"> <span style="font-weight: 550; font-size: 15px">SEAT</span>
                        <br> <span style="color: rgb(69, 68, 67); font-size: 25px"><b>%seat%</b></span> 
                     </div>
                     <div style="width: 80px; height: 70px"> <span style="font-weight: 550; font-size: 15px">ROW</span>
                        <br> <span style="color: rgb(69, 68, 67); font-size: 25px;"><b>%row%</b></span> 
                     </div>
                  </div>
                  <div>
                     <span style="font-size: 11px; color: rgb(147, 47, 60)">GATE CLOSES 30 MINUTES BEFORE EVENT START</span>
                  </div>
               </div>
               <div style="width: 185px; display: flex; justify-content: center; flex-direction: column; padding-top: 30px">
                  <div style="display: flex; justify-content: center; width: 100%">
                     <div>
                        <span style="font-weight: 550; font-size: 16px">EVENT TIME</span>
                        <br>
                        <div style="display: flex;flex-direction: column;"> <span style="font-size: 25px"><b>%time%</b></span> <span style="color: rgb(69, 68, 67); font-size: 20px;">%date%</span> </div>
                     </div>
                  </div>
                  <div style="display: flex;justify-content: center; align-items: center; height: 200px"> <img src="%qrCode%" width="200"> </div>
               </div>
            </div>
         </div>
      </div>
      <div style="width: 496px; height: 23px; background: rgb(147, 47, 60); border-radius: 0 0 10px 10px;color: white; font-family: Helvetica; display: flex; justify-content: space-between; padding-right: 12px; padding-left: 12px; font-size: 15px; padding-top: 5px; -webkit-print-color-adjust: exact; ">
         <span>
         <b>WWW.YABOUS.ORG</b>
         </span>
         <span>
         <b>YABOUS</b>
         </span>
      </div>
   </div>
</body>

JS code

    const options = {
        silent: false,
        marginType: 1,
        landscape: true,
        pagesPerSheet: 1,
        collate: true,
        copies: 1,
        printBackground: true,
        pageSize: {
          height: 454,
          width: 471
        }
    }

    let win2 = new BrowserWindow({
        height: 454,
        width: 471,
        icon: __dirname + `/dist/storyteller/assets/favicon.ico`
    });

    win2.setMenu(null);

    win2.loadURL(page);
    // win2.webContents.reload();
    // let win = BrowserWindow.getAllWindows()[0]; 

    win2.webContents.on('did-finish-load', () => {
        win2.webContents.print(options, (success, failureReason) => {
            if (!success) console.log(failureReason);

            console.log('Print Initiated');
        });
    })

Print Result

Print page result

I need to remove white spaces around the ticket and make the ticket fit the page.

1 Answers

According to Electron's documentation on webContents.print (), the pageSize object must only specify a height property (although it is declared to provide both width and height in a Size object). Since the docs are ambiguous about the width, I guess it will be calculated to match one of the listed supported page formats if the operating system does not report it to Electron as "supported". Thus, since your height does not match any of the supported formats (of your operating system), Electron defaults to A4.

One could argue that the reason for this is that the most consumer printers use one of the listed paper size formats anyway and that mishaps can be prevented by not allowing any other paper format. Also, Chrome doesn't allow to set an arbitrary page height/width via its UI, which probably is also the reason why Electron doesn't implement this (Electron is based on Chromium, the development version of Chrome).

If you have to keep the page size at your special format, the webContents.printToPDF () method is probably the next best thing as it allows to specify arbitrary width and height measurements. The linked documentation page gives an example of how to use this function to write to a file. You could then invoke an external PDF reader and print the file from there, but this is content for a new question.

In case you do not have a specialised printer capable of printing on 471mm x 454mm paper, I suggest to stick with A4. If you need the page in PDF format, simply refer to the documentation linked above. And since it seems you're writing some sort of ticketing software: In case you prepare PDF files for customers, also stick with A4 and let the customers fold the paper to the required format. That's how most online-bought tickets in Europe work.

Related