如何在Angular 2中打印PDF文件

11

我有一个 PDF 文件的 URL,例如: "test.example.com/incoice/1/download?auth_token="some_token",当我访问这个 URL 时,浏览器会在页面中显示 PDF。

现在我想使用打印功能打开此 PDF,也就是说,用户不必按 CTRL+P,我希望可以从我的代码中实现。

我尝试使用 iframe,但出现了跨域错误。以下是我使用的演示代码:

//first try

 let _printIframe;
var iframe = _printIframe;
if (!_printIframe) {
    iframe = _printIframe = document.createElement('iframe');
    document.body.appendChild(iframe);

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

// second try 
   // SRC of pdf
iframe.src = "Some API URl " + "/download?access_token=" + 
this.authenticationService.currentTokenDetails.access_token;
let url = iframe.src + "&output=embed";

window.frames["printf"].focus();
window.frames["printf"].print();
var newWin = window.frames["printf"];
newWin.document.write('<body onload="window.print()">dddd</body>');
newWin.document.close();

我在 Plunker 上创建了一个演示程序以打印 PDF。http://embed.plnkr.co/WvaB9HZicxK6tC3OAUEw/ 在这个演示中,我在新窗口中打开了 PDF,但我想直接打印这个 PDF。我该怎么做?

任何建议都会受到赞赏,如果我有错误,您可以进行更正。 谢谢。

3个回答

37

因此,我已经找到了解决方法。在我的情况下,我的API返回的是PDF二进制数据,而浏览器无法将该二进制数据打印到window.print中,所以我首先将二进制数据转换为blob数据,然后创建Iframe以进行打印。以下是它的代码。

const url = request URL // e.g localhost:3000 + "/download?access_token=" + "sample access token";
this.http.get(url, {
  responseType: ResponseContentType.Blob
}).subscribe(
  (response) => { // download file
    var blob = new Blob([response.blob()], {type: 'application/pdf'});
    const blobUrl = URL.createObjectURL(blob);
      const iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      iframe.src = blobUrl;
      document.body.appendChild(iframe);
      iframe.contentWindow.print();
});

给你了!希望这能帮助任何遇到这个问题的人 :)


Thank you very much for this - catu
2
需要注意的是,这在微软浏览器(IE和Edge)上不起作用。这里有一个关于如何解决这个问题的问题。如果你只想打开或保存blob,你可以参考这个 - rmlarsen
谢谢,有没有不弹出打印对话框的打印解决方案? - Sam khan
1
我认为这在火狐浏览器上不起作用。查看更多:https://dev59.com/W1wX5IYBdhLWcg3w6S4h - Shmarkus
如何在一次点击中打印多个文件 - Sunil Garg

3

以前的解决方案可能会在新版浏览器中引起一些安全问题,因此我们需要使用DOMSanitizer来将其变为安全资源。

export class PrintPdfService {
  constructor(protected sanitizer: DomSanitizer) {}

  printPdf(res) {
    const pdf = new Blob([res], { type: 'application/pdf' });
    const blobUrl = URL.createObjectURL(pdf);
    const iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    iframe.src = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.sanitizer.bypassSecurityTrustResourceUrl(blobUrl));
    document.body.appendChild(iframe);
    iframe.contentWindow.print();
  }
}

Angular DOMSanitizer


-3

好的,我会尝试。 - Vishal
我尝试了一下,但对我没有用。你能创建一个演示的 Plunker 吗? - Vishal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接