In PDF trực tiếp từ JavaScript


93

Tôi đang xây dựng một danh sách các tệp PDF trong HTML. Trong danh sách, tôi muốn bao gồm một liên kết tải xuống và một nút / liên kết in. Có cách nào để mở trực tiếp hộp thoại In cho tệp PDF mà người dùng không nhìn thấy tệp PDF hoặc mở trình xem PDF không?

Một số biến thể của việc tải tệp PDF vào iframe ẩn và kích hoạt nó để in bằng JavaScript?

Câu trả lời:


56

Dựa trên các nhận xét bên dưới, nó không còn hoạt động trong các trình duyệt hiện đại
Câu hỏi này cho thấy một cách tiếp cận có thể hữu ích cho bạn: Im lặng in một tệp PDF nhúng

Nó sử dụng <embed>thẻ để nhúng PDF vào tài liệu:

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

Sau đó, bạn gọi .print()phương thức trên phần tử trong Javascript khi tệp PDF được tải:

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();
    }
}

Bạn có thể đặt bản nhúng trong iframe ẩn và in nó từ đó, mang lại cho bạn trải nghiệm liền mạch.


3
Giải pháp này không làm việc ... Tôi nhận được sự cho phép từ chối dành cho Chrome, FF
user1428716

8
Điều này sẽ không hoạt động nếu tài liệu được nhúng nằm trên một miền khác.
nullability

5
Dễ dàng hơn chỉ cần thêm javascript vào pdf để in khi kết xuất. Đây là những gì Google Tài liệu làm. Bằng cách này, trình duyệt sẽ tải và in nó hoặc plugin adobe.
Rahly

2
Bạn có thể google nó, nhưng tất cả chỉ là một đối tượng script mới được thêm vào pdf, trong đó javascript chỉ là "window.print ()"
Rahly

6
Vâng, tôi đang gặp sự cố trên tất cả các trình duyệt trong đó phương thức print () không được xác định. Phương pháp này có lỗi thời không? Có bất kỳ giải pháp khác?
Jacob Ensor

38

Đây là một chức năng để in PDF từ iframe.

Bạn chỉ cần chuyển URL của PDF cho hàm. Nó sẽ tạo iframe và kích hoạt in khi PDF được tải.

Lưu ý rằng hàm không phá hủy iframe. Thay vào đó, nó sử dụng lại nó mỗi khi hàm được gọi. Thật khó để phá hủy iframe vì nó cần thiết cho đến khi in xong và phương pháp in không có hỗ trợ gọi lại (theo như tôi biết).

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
Tôi gửi lời cảm ơn đến bạn, vì bạn đã giúp tôi giải quyết một vấn đề lớn: nếu không có setTimeout, chức năng in đôi khi sẽ bị lỗi. Không biết tại sao và hy vọng ai đó sẽ tìm ra nó.
Evan Hu,

Phương thức in có hỗ trợ gọi lại, nhưng nó vẫn chưa được hỗ trợ rộng rãi khi bạn viết câu trả lời này vào năm 2014. Tuy nhiên, hiện tại; các phiên bản mới nhất của tất cả các trình duyệt máy tính để bàn chính đều hỗ trợ onafterprint. Tôi hơi lo ngại rằng việc sử dụng lại iframe có thể dẫn đến các điều kiện đua trong đó ai đó nhấp vào hai nút nhanh chóng và kết thúc in tệp PDF thứ hai hai lần vì URL iframe đã bị hoán đổi trước khi hộp thoại in đầu tiên xuất hiện.
Mark Amery

18

Tải xuống Print.js từ 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")
});

3
Không in PDF trên IE, Edge hoặc Firefox.
Richard Collette

Hôm nay đã thử điều này bằng cách sử dụng jQuery để lấy các byte pdf từ máy chủ, sau đó tạo blob và 'createOvjectURL' như trên. PrintJS không hiển thị hộp thoại in trong trường hợp này. :)
woohoo

tôi có thể in nhiều tệp pdf chỉ với một cú nhấp chuột không?
Sunil Garg

12

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

để có bản demo trực tiếp http://mozilla.github.io/pdf.js/

Đó có thể là những gì bạn muốn, nhưng tôi không thể thấy điểm này vì các trình duyệt hiện đại bao gồm chức năng như vậy, nó cũng sẽ chạy rất chậm trên các thiết bị có công suất thấp như thiết bị di động, nhân tiện, có các plugin và ứng dụng được tối ưu hóa của riêng họ .


Pdf.js cũng là terribly chậm khi in tài liệu lớn, như 80MB +
Rudolf Dvoracek

6

Tôi đã sử dụng chức năng này để tải xuống luồng pdf từ máy chủ.

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)
    }

4

Giải pháp trình duyệt chéo để in pdf từ chuỗi base64:

  • Chrome: cửa sổ in được mở
  • FF: tab mới với pdf được mở
  • IE11: lời nhắc mở / lưu được mở

.

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))

THƯỞNG - Mở tệp blob trong tab mới cho IE11

Nếu bạn có thể thực hiện một số xử lý trước chuỗi base64 trên máy chủ, bạn có thể hiển thị nó dưới một số url và sử dụng liên kết trong printJS:)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.