chrome浏览器直接打印pdf文件

2,517 阅读2分钟

简介

1、谷歌浏览器可以直接将网页打印成pdf, crtl+p 或者使用工具栏都可以。
2、如果是pdf文件,可以直接新开窗口,打开这个pdf文件,使用浏览器的打印功能。
3、但是,有时候产品会要求你直接弹出打印某个pdf文件的弹框,(就是上面点击打印按钮之后的弹窗)直接打印
4、虽然我觉得有点多余,但是奈何产品有这样的要求。。。。
然后就出现了下面的解决方案:

非跨域场景

如果pdf文件地址是不跨域的(理想很丰满...),动态生成一个iframe,iframe的src指定为pdf文件地址
1.直接调用子iframe的window.print方法,直接打印浏览的pdf

<iframe id="aaa" src="/static/1.pdf"/>
document.getElementById('aaa').contentWindow.print()

跨域场景

一般资源都是存放在cdn上,而不是当前网站的域名下,所以一般都是要跨域的
思路如下:
1.以二进制的形式加载资源
2.生成一个iframe
3.调用iframe的打印方法


    // 1.下载资源
    const url = 'xxx.pdf'
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true) // 异步
    xhr.responseType = 'blob' // blob 类型
    xhr.onload = () => {
      if (xhr.status != 200) {
        alert('下载异常!')
        return
      }
      const newUrl = window.URL.createObjectURL(xhr.response)
      // 调用print函数
      print(newUrl)
    }
    xhr.send()


    //2. 创建iframe调起打印
    print(newUrl) {
      const iframe = document.createElement('IFRAME')
      iframe.src = newUrl
      document.body.appendChild(iframe)
      const doc = iframe.contentWindow.document
      iframe.contentWindow.focus()
      iframe.contentWindow.print()
    }

tips:这种方式的问题是必须把整个pdf下载下来之后才会走生成pdf的逻辑,如果pdf很大的话,时间会比较久,并且没有load状态显示,当然也可以自己加个loading

其他跨域资源的下载

一般的图片,pdf等浏览器可以直接打开的资源,如果跨域的情况下使用

<!-- 这种可以直接下载 -->
<a href="/static/images/header-logo_5f983a.png" download>图片</a>
<!-- 这种无法直接下载 -->
<a href="https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071010.png" download>图片</a>

都会直接打开文件,而不会去下载

也可以使用类似的思路,以二进制的格式将资源下载下来,然后创建个a标签,就没有跨域的问题了

    download() {
      var url = "https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071010.png"
      var xhr = new XMLHttpRequest()
      xhr.open('GET', url, true) // 异步
      xhr.responseType = 'blob' // blob 类型
      xhr.onload = function () {
        if (xhr.status != 200) {
          alert('下载异常!')
          return
        }
        if (window.navigator.msSaveOrOpenBlob) {
          // IE
          navigator.msSaveBlob(xhr.response, filename)
        } else {
          var newUrl = window.URL.createObjectURL(xhr.response)
          var a = document.createElement('a')
          a.setAttribute('href', newUrl)
          a.setAttribute('target', '_blank')
          a.setAttribute('download', true) // 自定义文件名(有效)
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
        }
      }
      xhr.send()
    },

某些平台直接下载跨域资源的支持

我们公司使用的是七牛云,他提供了一个文档 developer.qiniu.com/kodo/1659/d…

<a :href="http://baidu.com/a.pdf?attname=a.pdf}`">下载</a>

加上后缀,资源即使跨域了,也可以直接下载,棒棒哒!!!