crabbly / Print.js

A tiny javascript library to help printing from the web.
MIT License
4.29k stars 672 forks source link

impossible to print a pdf from a mobile or ipad. #549

Open adrien426 opened 3 years ago

adrien426 commented 3 years ago

Go to the official website: https://printjs.crabbly.com/ and try to print the pdf examples. it does not work on mobile or even on pc in mobile emulation mode. ps. I tried it on mobile with chrome fierfox. etc .. how to fix this problem? thank you :) Screenshot_20210326-184923_Chrome

fredericoregateiro commented 3 years ago

Notice the same thing

ahirpar commented 3 years ago

Any update? @crabbly

bjoernfal commented 3 years ago

Right now, iPad is working, but not Chrome on Android (see issue #438).

cesarlarsson commented 3 years ago

The issue that have in the ipad/ safari is that just show the first page to print, on chrome tries to print the web page and not the document

markbreuss commented 3 years ago

I am seeing the same issue on Android with Chrome and using the base64 PDF printing. Does anyone have a temporary workaround for this?

dmop commented 3 years ago

image The android chrome is not opening the iframe that the library creates, that's the problem, I didn't found a way to print directly, what I'm doing right now is creating a blobUrl and opening it, this will open the file on another tab, where you can see the preview and click to print, if you want:



  const blobPdfFromBase64String = base64String => {
    const byteArray = Uint8Array.from(
      atob(base64String)
        .split('')
        .map(char => char.charCodeAt(0))
    );
    return new Blob([byteArray], { type: 'application/pdf' });
  };

  const downloadBlob = (blob) => {
    const blobUrl = URL.createObjectURL(blob);
    window.open(blobUrl, '_blank')
  };

   const base64Pdf = ""
   const blob = blobPdfFromBase64String(base64Pdf);
   downloadBlob(blob);
woowalker commented 1 year ago

still now?any help?

URVESH1121 commented 3 months ago
export const printPdf = (() => {
  const isFirefox = /Gecko\/\d/.test(navigator.userAgent);
  const isAndroid = /Android/.test(navigator.userAgent);
  const firefoxDelay = 1000;
  let iframe;

  return function (url) {
    if (iframe) {
      iframe.parentNode.removeChild(iframe);
    }

    iframe = document.createElement("iframe");
    iframe.style.cssText =
      "width: 1px; height: 100px; position: fixed; left: 0; top: 0; opacity: 0; border-width: 0; margin: 0; padding: 0";

    const xhr = new XMLHttpRequest();
    try {
      xhr.responseType = "arraybuffer";
    } catch (e) {
      window.open(url, "_blank");
      return;
    }

    xhr.addEventListener("load", function () {
      if (xhr.status === 200 || xhr.status === 201) {
        const pdfBlob = new Blob([xhr.response], { type: "application/pdf" });
        const iframeUrl = URL.createObjectURL(pdfBlob);
        iframe.src = iframeUrl;

        iframe.addEventListener("load", function () {
          const openPrintPreview = () => {
            try {
              iframe.focus();
              iframe.contentWindow.print();
            } catch (error) {
              console.error("Print preview failed: " + error, error);
            } finally {
              URL.revokeObjectURL(iframeUrl);
            }
          };

          if (isFirefox) {
            window.setTimeout(openPrintPreview, firefoxDelay);
          } else if (isAndroid) {
            const newWindow = window.open("", "_blank");
            if (newWindow) {
              newWindow.document.write(`
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <title>Print PDF</title>
                    <style>
                        /* CSS Reset */
                        * {
                            margin: 0;
                            padding: 0;
                            box-sizing: border-box;
                        }

                        html, body {
                            width: 100%;
                            height: 100%;
                            overflow: hidden;
                        }

                        #printButton {
                            position: fixed;
                            bottom: 10px;
                            left: 50px;
                            z-index: 9999;
                            padding: 10px;
                            background: #1F51FF;
                            color: #fff;
                            cursor: pointer;
                        }

                        #pdfContainer {
                            width: 100%;
                            height: 100%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                        }

                        @media print {
                            #printButton {
                                display: none;
                            }

                            html, body, #pdfContainer {
                                margin: 0 !important;
                                padding: 0 !important;
                                width: 100%;
                                height: 100%;
                                overflow: hidden !important;
                            }

                            #pdfContainer canvas {
                                width: 100% !important;
                                height: 100% !important;
                            }
                        }
                    </style>
                </head>
                <body>
                <button id="printButton">Print</button>
                <div id="pdfContainer"></div>

                <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
                <script>
                    document.getElementById('printButton').addEventListener('click', function() {
                        window.print();
                    });

                    // Initialize PDF.js
                    const pdfContainer = document.getElementById('pdfContainer');
                    const loadingTask = pdfjsLib.getDocument("${iframeUrl}"); // Use the blob URL created for the PDF
                    loadingTask.promise.then(function(pdf) {
                        // Fetch the first page
                        pdf.getPage(1).then(function(page) {
                            const scale = 2; // Adjust scale to ensure full-page fit
                            const viewport = page.getViewport({ scale: scale });
                            const canvas = document.createElement('canvas');
                            const context = canvas.getContext('2d');
                            canvas.height = viewport.height;
                            canvas.width = viewport.width;
                            const renderContext = {
                                canvasContext: context,
                                viewport: viewport
                            };
                            page.render(renderContext).promise.then(function() {
                                pdfContainer.innerHTML = '';
                                pdfContainer.appendChild(canvas);
                                // Adjust canvas to fit the container
                                canvas.style.width = '100%';
                                canvas.style.height = '100%';
                            });
                        });
                    });
                </script>
                </body>
                </html>
                `);
              newWindow.document.close();
            } else {
              alert("Please allow popups for this website");
            }
          } else {
            openPrintPreview();
          }
        });

        document.body.appendChild(iframe);
      }
    });

    xhr.open("GET", url, true);
    xhr.send();
  };
})();

This is the complete function code, compatible with both PC and mobile devices, and all browsers.