stephanrauh / ngx-extended-pdf-viewer

A full-blown PDF viewer for Angular 16, 17, and beyond
https://pdfviewer.net
Apache License 2.0
450 stars 167 forks source link

On adding div to the document body in beforePrint event , an extra page is being added to the document while printing #2298

Closed NaivedyaMishra1 closed 2 months ago

NaivedyaMishra1 commented 2 months ago

I am appending a div to the body of the document when the user clicks on print button using the beforePrint event. An extra page is being added due to this to the document. Could you please help me in this. Thanks

stephanrauh commented 2 months ago

Where do you add the div precisely? If you simply add it to the <html> or <body>, there shouldn't be an extra page. There might be an extra page when you add it to the <div class="printcontainer">. The CSS rule responsible for hiding everything but the print looks like so:

@media print {
  body[data-pdfjsprinting] > * {
    display: none !important;
  }
  body[data-pdfjsprinting] #printContainer {
    display: block !important;
  }
  body[data-pdfjsprinting] #printContainer div img {
    height: 100vh !important;
  }
}

Experiment with the CSS rules to find out what's going on. Probably you only have to add a clever CSS rule to your global styles.(s)css file.

stephanrauh commented 2 months ago

I hope I've managed to give you enough cues to solve the problem yourself, so I'm closing the ticket now. If you still need help, just add a comment.

NaivedyaMishra1 commented 2 months ago

Hi @stephanrauh , Thanks for your reply, I have appended the div to the body . The thing is that the div has position 'fixed'. For eg. the css for the div is

.print-div {
  display: grid;
  position: fixed;
}

and in this case it is adding an extra page to the document.

if I try adding a div with display: 'block' its adding the content to the 2nd page and not the first, but in this case the extra page is not being added.

stephanrauh commented 2 months ago

Maybe it's a stupid question, and it's not my business - but why do you add a div before printing?

The print algorithm works like so:

It seems your <div> confuses the algorithm. I don't know why that happens. Actually, I don't know why you're adding the <div> in the first place. Do you want to add the <div> to the print? Or should it be visible on the screen?

NaivedyaMishra1 commented 2 months ago

HI @stephanrauh , I am adding watermark to the printed text using the div and My goal is achieved by adding the div, but that extra page is my concern. Is there a better way to add watermarks in the print which you can suggest.

stephanrauh commented 2 months ago

Now we're getting closer! Most likely, your watermark spills over to the next page. Even if it's only a fraction of a pixel, there's an additional page. Or maybe, it's not the watermark that spills over, but it pushes something else down or increases the page size.

For example, you can try adding this CSS rule to your global styles.(s)css:

@media print {
  #printContainer > .printedPage {
    width: 99%;
  }
}

Play around with the percentage and the CSS selector to find the optimal combination. It helped many people in the past. Your case is a bit different because you're adding a <div>, so I don't have any experience, but I guess this should to the trick.

Alternatively, you can add the watermark as a text or stamp annotation (using the text editor or it's programmatic API). But that'd be much more work.

NaivedyaMishra1 commented 2 months ago

HI @stephanrauh , I tried you solution i.e. @media print {

printContainer > .printedPage {

width: 99%;

} } and played around with the css above as well as that of my watermark div but I have got no luck with it.

In firefox, the print works flawlessly without any change in code, i.e. it doen't display any blank page as the last page.

stephanrauh commented 2 months ago

It's time to debug your CSS rules. Here's how to do it in Google Chrome:

  1. set the attribute [minifiedJSLibraries]="false". This makes debugging the JavaScript code a lot easier.
  2. Locate the line print.call(window) and add a breakpoint at this line. This stops immediately before printing. The sourcecode below shows the entire method. I think it's located in the viewer-*.mjs file.
  3. Open the "rendering" tab of the Chrome developer tools and set the CSS media type to "print", as shown in the screenshot. I suppose this option is also there in other browsers, but it's probably in a different tab.

Now your screen shows exactly what's going to be printed. When you manipulate the CSS settings in the developer tools, the effect is immediately visible. This helped me a lot whenever I had trouble with printing. I hope it enables you to solve your issue, too!

Best regards, Stephan

image

  performPrint() {
    this.throwIfInactive();
    return new Promise(resolve => {
      // Push window.print in the macrotask queue to avoid being affected by
      // the deprecation of running print() code in a microtask, see
      // https://github.com/mozilla/pdf.js/issues/7547.
      setTimeout(() => {
        if (!this.active) {
          resolve();
          return;
        }
        print.call(window);
        // Delay promise resolution in case print() was not synchronous.
        // modified by ngx-extended-pdf-viewer #83
        const isIOS = navigator.platform && [
          "iPad Simulator",
          "iPhone Simulator",
          "iPod Simulator",
          "iPad",
          "iPhone",
          "iPod"
        ].includes(navigator.platform)
        // iPad on iOS 13 detection
        || (navigator.userAgent.includes("Mac") && "ontouchend" in document);

        setTimeout(resolve, isIOS ? 1500 : 20); // Tidy-up.
        // end of modification by ngx-extended-pdf-viewer
      }, 0);
    });
  }