พิมพ์ PDF โดยตรงจาก JavaScript


94

ฉันกำลังสร้างรายการ PDF ใน HTML ในรายการฉันต้องการรวมลิงค์ดาวน์โหลดและปุ่ม / ลิงค์พิมพ์ มีวิธีใดบ้างที่จะเปิดกล่องโต้ตอบพิมพ์สำหรับ PDF โดยตรงโดยที่ผู้ใช้ไม่เห็น PDF หรือเปิดโปรแกรมดู PDF

รูปแบบบางอย่างของการดาวน์โหลด PDF ลงใน iframe ที่ซ่อนอยู่และสั่งให้พิมพ์ด้วย JavaScript?

คำตอบ:


57

จากความคิดเห็นด้านล่างนี้ไม่สามารถใช้งานได้ในเบราว์เซอร์สมัยใหม่อีกต่อไป
คำถามนี้แสดงให้เห็นถึงแนวทางที่อาจเป็นประโยชน์สำหรับคุณ: พิมพ์ไฟล์ PDF ในตัว

ใช้<embed>แท็กเพื่อฝัง PDF ในเอกสาร:

<embed
    type="application/pdf"
    src="path_to_pdf_document.pdf"
    id="pdfDocument"
    width="100%"
    height="100%" />

จากนั้นคุณเรียกใช้.print()เมธอดบนองค์ประกอบใน Javascript เมื่อโหลด PDF:

function printDocument(documentId) {
    var doc = document.getElementById(documentId);

    //Wait until PDF is ready to print    
    if (typeof doc.print === 'undefined') {    
        setTimeout(function(){printDocument(documentId);}, 1000);
    } else {
        doc.print();
    }
}

คุณสามารถวางการฝังใน iframe ที่ซ่อนอยู่และพิมพ์จากที่นั่นทำให้คุณได้รับประสบการณ์ที่ราบรื่น


3
วิธีนี้ใช้งานไม่ได้ ... ฉันได้รับการอนุญาตจาก Chrome, FF
user1428716

8
วิธีนี้จะใช้ไม่ได้หากเอกสารที่ฝังอยู่ในโดเมนอื่น
nullability

5
ง่ายกว่าเพียงเพิ่ม javascript ลงใน pdf เพื่อพิมพ์เมื่อแสดงผล นี่คือสิ่งที่ Google เอกสารทำ ด้วยวิธีนี้เบราว์เซอร์จะโหลดและพิมพ์หรือปลั๊กอิน adobe
Rahly

2
คุณอาจใช้ Google ได้ แต่ทั้งหมดนี้คือวัตถุสคริปต์ใหม่ที่เพิ่มเข้ามาใน pdf โดยที่จาวาสคริปต์เป็นเพียง "window.print ()"
Rahly

6
ใช่ฉันมีปัญหาในเบราว์เซอร์ทั้งหมดที่ไม่ได้กำหนดวิธีการพิมพ์ () วิธีนี้ล้าสมัยหรือไม่? มีวิธีแก้ไขอื่น ๆ หรือไม่?
Jacob Ensor

40

นี่คือฟังก์ชั่นในการพิมพ์ PDF จาก iframe

คุณเพียงแค่ต้องส่ง URL ของ PDF ไปยังฟังก์ชัน มันจะสร้าง iframe และเรียกพิมพ์เมื่อโหลด PDF

โปรดทราบว่าฟังก์ชันไม่ได้ทำลาย iframe แต่จะนำกลับมาใช้ใหม่ทุกครั้งที่เรียกใช้ฟังก์ชัน เป็นการยากที่จะทำลาย iframe เนื่องจากจำเป็นจนกว่าการพิมพ์จะเสร็จสิ้นและวิธีการพิมพ์ไม่มีการรองรับการโทรกลับ (เท่าที่ฉันรู้)

printPdf = function (url) {
  var iframe = this._printIframe;
  if (!this._printIframe) {
    iframe = this._printIframe = document.createElement('iframe');
    document.body.appendChild(iframe);

    iframe.style.display = 'none';
    iframe.onload = function() {
      setTimeout(function() {
        iframe.focus();
        iframe.contentWindow.print();
      }, 1);
    };
  }

  iframe.src = url;
}

3
ฉันขอขอบคุณคุณในขณะที่คุณช่วยฉันแก้ปัญหาใหญ่: หากไม่มีsetTimeoutฟังก์ชันการพิมพ์จะล้มเหลวในบางครั้ง ไม่รู้ว่าทำไมและหวังว่าจะมีคนค้นพบ
Evan Hu

วิธีการพิมพ์มีการสนับสนุนการโทรกลับ แต่ยังไม่ได้รับการสนับสนุนอย่างกว้างขวางเมื่อคุณเขียนคำตอบนี้ในปี 2014 ตอนนี้แม้ว่า; onafterprintรุ่นล่าสุดของทุกการสนับสนุนเบราว์เซอร์สก์ท็อปที่สำคัญ ฉันกังวลเล็กน้อยว่าการใช้ iframe ซ้ำอาจทำให้เกิดเงื่อนไขการแข่งขันที่ใครบางคนคลิกที่ปุ่มสองปุ่มอย่างรวดเร็วและจบลงด้วยการพิมพ์ PDF ที่สองสองครั้งเนื่องจาก URL ของ iframe ถูกสลับออกไปแล้วก่อนที่กล่องโต้ตอบการพิมพ์ครั้งแรกจะปรากฏขึ้น
Mark Amery

18

ดาวน์โหลด Print.js จากhttp://printjs.crabbly.com/

$http({
    url: "",
    method: "GET",
    headers: {
        "Content-type": "application/pdf"
    },
    responseType: "arraybuffer"
}).success(function (data, status, headers, config) {
    var pdfFile = new Blob([data], {
        type: "application/pdf"
    });
    var pdfUrl = URL.createObjectURL(pdfFile);
    //window.open(pdfUrl);
    printJS(pdfUrl);
    //var printwWindow = $window.open(pdfUrl);
    //printwWindow.print();
}).error(function (data, status, headers, config) {
    alert("Sorry, something went wrong")
});

4
ไม่พิมพ์ PDF บน IE, Edge หรือ Firefox
Richard Collette

ลองใช้วันนี้โดยใช้ jQuery get เพื่อรับไบต์ของ pdf จากเซิร์ฟเวอร์จากนั้นสร้าง blob และ "createOvjectURL" ตามด้านบน PrintJS ไม่แสดงกล่องโต้ตอบการพิมพ์ในกรณีนี้ :)
woohoo

ฉันสามารถพิมพ์ไฟล์ pdf หลายไฟล์ด้วยการคลิกเพียงครั้งเดียวได้หรือไม่
Sunil Garg

12

https://github.com/mozilla/pdf.js/

สำหรับการสาธิตสดhttp://mozilla.github.io/pdf.js/

อาจเป็นสิ่งที่คุณต้องการ แต่ฉันไม่สามารถมองเห็นประเด็นนี้ได้เนื่องจากเบราว์เซอร์สมัยใหม่มีฟังก์ชันดังกล่าวนอกจากนี้มันจะทำงานช้ามากบนอุปกรณ์ที่ใช้พลังงานต่ำเช่นอุปกรณ์มือถือที่มีปลั๊กอินและแอปที่เหมาะสม .


Pdf.js นั้นช้ามากเมื่อพิมพ์เอกสารขนาดใหญ่เช่น 80MB +
Rudolf Dvoracek

6

ฉันใช้ฟังก์ชันนี้เพื่อดาวน์โหลดสตรีม pdf จากเซิร์ฟเวอร์

function printPdf(url) {
        var iframe = document.createElement('iframe');
        // iframe.id = 'pdfIframe'
        iframe.className='pdfIframe'
        document.body.appendChild(iframe);
        iframe.style.display = 'none';
        iframe.onload = function () {
            setTimeout(function () {
                iframe.focus();
                iframe.contentWindow.print();
                URL.revokeObjectURL(url)
                // document.body.removeChild(iframe)
            }, 1);
        };
        iframe.src = url;
        // URL.revokeObjectURL(url)
    }

5

โซลูชันเบราว์เซอร์ข้ามสำหรับการพิมพ์ pdf จากสตริง base64:

  • Chrome: เปิดหน้าต่างการพิมพ์
  • FF: เปิดแท็บใหม่พร้อม pdf
  • IE11: เปิด / บันทึกพร้อมต์เปิดอยู่

.

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

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // or however you want to check it

const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

printPDF(blobPdfFromBase64String(base64String))

โบนัส - การเปิดไฟล์ blob ในแท็บใหม่สำหรับ IE11

หากคุณสามารถทำการประมวลผลสตริง base64 ล่วงหน้าบนเซิร์ฟเวอร์ได้คุณสามารถแสดงได้ภายใต้ url และใช้ลิงก์ในprintJS:)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.