接到一个移动端网页pdf预览的需求,首先想到的方案是利用iframe进行显示。
后端响应头设置

Content-Disposition: inline

Content-Disposition

一般有以下几种情况

// inline 默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示
Content-Disposition: inline   
// attachment 意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框
Content-Disposition: attachment
// filename 下载后的文件名
Content-Disposition: attachment; filename="filename.jpg"

按照正常思维,设置之后,应该在iframe里面展示pdf内容。
在PC端模拟器测试时,一切与预期一致。但是到了移动端浏览器,就不同了。

iphone手机 自带的safari、微信、企业微信自带的浏览器都与预期一致。
Android手机(huawei mate9),在企业微信自带浏览器,是新窗口打开了pdf,在微信自带浏览器和手机自带浏览器,都是提示下载

效果与需求不一致

pdf.js

简介

PDF.js是使用HTML5构建的可移植文档格式(PDF)查看器。

PDF.js由社区驱动,并受Mozilla支持。目标是创建一个基于Web标准的通用平台,用于解析和呈现PDF。

pdfjs 在npm仓库提供了一个叫pdfjs-dist包。

引入pfdjs

const PDFJS = require("@/pdfjs-dist");
const workerSrc = require("@/pdfjs-dist/es5/build/pdf.worker.entry.js");
PDFJS.GlobalWorkerOptions.workerSrc = workerSrc;

下载pdf

const CMAP_URL = "https://unpkg.com/pdfjs-dist@2.5.207/cmaps/";
const loadingTask: any = PDFJS.getDocument({
    url: this.pdfUrl,
    cMapUrl: CMAP_URL,
    cMapPacked: true,
    withCredentials: true,
});
loadingTask.promise
    .then((pdfDoc_) => {
        // 拿到pdf可以存起来,用于接下来的展示
    })
    .catch((error: any) => {

    });

获取某一页的内容

this.pdfDoc
    .getPage(num)
    .then(
      (page: any) => {
        const viewport = page.getViewport({ scale: 1 });

        canvas.height = viewport.height;
        canvas.width = viewport.width;
        canvas.style.width = "100%";
        
        const renderContext = {
          canvasContext,
          viewport: viewport,
        };
        page.render(renderContext);
      }
    )
    .catch((e: any) => {
      console.info(e);
    });

问题

  • pdf展示模糊

在高分辨率屏幕上,pdf可能会显示的不太清晰。
这是canvas 属性上设置的width/height是指物理像素,如果devicePixelRatio的值为2,那么意味着一个css像素相当于2个物理像素。按照上面的设置,canvas的css宽度值与canvas的物理像素值一致,将会导致canvas画布被放大,展示变得模糊。
于是,根据屏幕的像素比,设置scale的值,使得在不同分辨率的设备,都能得到清晰的体验效果。

  • pdf部分字体不显示

引入字体库

  const CMAP_URL = "https://unpkg.com/pdfjs-dist@2.5.207/cmaps/";  // 字体库地址
  const loadingTask: any = PDFJS.getDocument({
    url: this.pdfUrl,
    cMapUrl: CMAP_URL,
    cMapPacked: true,
    withCredentials: true,
  });
  • 签章不显示

手动修改源码
因为库的作者处于安全考虑,如果是Sig类型,会隐藏,所以,也没法指望作者放开了。只能自己手动。
pdf.worker.js
image.png

pdf下载

不同浏览器,依然表现不太一致

在微信里

先展示一个诱导下载QQ浏览器的页面,需要选择【其他方式下载】,多了一步,还好,能实现下载
image.png

在企业微信里

下载后直接预览

在自带的浏览器里

image.png


southnan0
156 声望8 粉丝

欲买桂花同载酒,终不似,少年游


« 上一篇
git 常用操作
下一篇 »
Taro调研