博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IPhone和安卓预览word和PDF文件之路
阅读量:7276 次
发布时间:2019-06-29

本文共 4224 字,大约阅读时间需要 14 分钟。

前言

这篇文章主要是为了总结一下最近做微信内置浏览器预览文件?(word和pdf)在不同操作系统的问题。在IPhone微信内置浏览器中,基本可以预览各式各样的文件格式,但是在安卓就不行了,打开文件地址就跳转到浏览器下载页面了。以下就是本人的踩坑之路。

~~敢问路在何方,路就在脚下

官网demo( ),其原理是绘制成canvas

解决方式

  1. PDF在ios和安卓的预览
  • 安卓:PDF.JS(地址 ) 来解析pdf文件(自己的页面,可以转发分享,通过JS-SDK设置)
  • IOS: 微信自带的预览功能(不能分享,因为这个页面是微信自己的,所以改不了),也可以改成PDFJS来实现跟安卓一样的(微信本身的如果图文复杂的word预览也会有点错乱)
  1. Word在ios和安卓的预览
  • 后端将word转成PDF文件,前端在通过PDF实现ios和安卓的预览
  • 后端可以转换成图片,这样就可以直接渲染了
    注:前端我暂时没找到好的办法将word转换成PDF?,所以通过后端转换来实现。后端用linux转的话如果图文比较复杂的话会出现图文错乱的问题,所以建议通过购买Window系统的服务器来转换(坑),也可以在阿里云市场购买服务(?不太推荐,还是有点小贵的)

PDFJS准备工作

  • pdf.js可以从上clone下来,然后本地gulp生成可用的pdf.js和pdf.worker.js(参考readme即可)。不过,本人推荐还是用npm安装,npm install pdfjs-dist --S,然后在项目中通过import PDFJS from 'pdfjs-dist引用就可以用了
  • pdf.js不能处理跨域文件和本地文件,所以本地调试的时候应该请求服务器的文件,如果请求的是远程服务器,存在跨域,那就需要在config/index.js中配置一下代理
proxyTable: {      '/media': {        target: 'https://xxxx.cn', // 换成正确的服务器域名        changeOrigin: true,        pathRewrite: {          '^/media': '/media'        }      }    }原文:https://blog.csdn.net/u010419337/article/details/79535131复制代码

这样的话请求里面包含media的会被替换成target那个域名,OK,完美?

核心代码

项目安装好pdfjs-dist后就通过下面代码引入文件

import PDFJS from 'pdfjs-dist'import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'import 'pdfjs-dist/web/pdf_viewer.css'PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js'复制代码

一和四这两个文件包含了获取、解析和展示PDF的方法,但是解析和渲染PDF需要较长的时间,所以pdfjs通过依赖HTML5的web Worker,从而从主线程中移除大量的CPU操作来提升性能。 二和三的文件主要是为了来实现渲染出来的pdf可以复制里面的文字,也相当于将里面的图文用真实的文字和图片通过html渲染出来。如果没有这一步的话生成的是一个个canvas

// 页面上写个容器div class="file_preview" ref="filePreview">    
复制代码
let containerlet url = '你的pdf文件地址.pdf'(线上环境真实存在的文件)// 通过getDocument以块的形式请求文档,返回PromisePDFJS.getDocument(url).then((pdf) => {    // 获取容器    container = document.getElementById('container')    // 获取pdf的总页数    let num = pdf.numPages    // 执行核心解析和渲染代码    this.renderPDF(pdf, num)  }).catch(err => {    console.log(err)  })复制代码

解析渲染函数

renderPDF (pdf, num) {      for (let i = 1; i<= num; i++) {        let pageDiv        pdf.getPage(i).then((page) => {         // 设置PDF尺寸,如果渲染出来的模糊的话这个稍微可以调大点,但是要给容器的canvas设置个样式,本人亲测过,如下样式设置          var viewport = page.getViewport(2)          pageDiv = document.createElement('div')          pageDiv.setAttribute('id', 'page-' + (page.pageIndex + 1))          pageDiv.setAttribute('style', 'position: relative')          container.appendChild(pageDiv)          var canvas = document.createElement('canvas')          pageDiv.appendChild(canvas)          var context = canvas.getContext('2d')          canvas.width = viewport.width          canvas.height = viewport.height                      var renderContext = {              canvasContext: context,              viewport: viewport          };          page.render(renderContext).then(() => {            // 返回PDF页面上的文本片段,为了实现文本复制            return page.getTextContent()          }).then((textContent) => {            // 创建文本图层div            const textLayerDiv = document.createElement('div')            textLayerDiv.setAttribute('class', 'textLayer')            // 将文本图层div添加至每页pdf的div中            pageDiv.appendChild(textLayerDiv)                        // 创建新的TextLayerBuilder实例            var textLayer = new TextLayerBuilder({                textLayerDiv: textLayerDiv,                pageIndex: page.pageIndex,                viewport: viewport            })                     textLayer.setTextContent(textContent)                   textLayer.render()          })        })      }    }复制代码
复制代码

分析以上函数用到的方法

参考( )

  • getDocument():用于异步获取PDf文档,发送多个Ajax请求以块的形式下载文档。它返回一个Promise,该Promise的成功回调传递一个对象,该对象包含PDF文档的信息,该回调中的代码将在完成PDf文档获取时执行
  • getPage():用于获取PDF文档中的各个页面
  • getViewport():针对提供的展示比例,渲染PDF的页面尺寸
  • render():渲染PDF

文本复制

以上引入的第三和第四个文件,就是用来解决文本复制的问题,通过使用Text-Layer来渲染。PDF.js支持在使用Canvas渲染的PDF页面上渲染文本图层。然而,这个功能需要用到额外的两个文件:text_layer_builder.jstext_layer_builder.css,引入这两个文件

import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'import 'pdfjs-dist/web/pdf_viewer.css'复制代码

主要代码如上“解析和渲染函数”

PDF.JS核心API的作用

  • page.render():返回一个当PDF成功渲染到页面上时的Promise,可以通过使用成功回调来渲染文字图层
  • page.getTextContent():获得PDF页面上的文本片段
  • TextLayerBuilder:有两个重要的方法,setTextContent()用于设置page.getTextContent()函数返回的文本片段;render()用于渲染文本图层

总结

强大的PDF.JS基本实现了预览PDF的问题,缺点是官网文档太过于精简了?,不过以上基本已经可以实现大部分需求了。产品再给你提需求还怕吗!!?

转载于:https://juejin.im/post/5cdfc3aaf265da1b7e10061b

你可能感兴趣的文章
【求助】怎样实如今并肩看中增加代码啊
查看>>
mysql 性能优化方案
查看>>
Java并发编程:volatile关键字解析
查看>>
Oracle Alert - APP-ALR-04108: SQL error ORA-01455
查看>>
【转】在linux内核中读写文件 -- 不错
查看>>
http put post请求区别
查看>>
android EventBus的简单使用
查看>>
在.net中使用GAC
查看>>
EasyExcel导入工具(SpringMVC下使用)
查看>>
【转载】查找怪数据数组的内存分布和地址(天龙八部)
查看>>
敏捷生活练习第14次活动:学会感恩
查看>>
Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
查看>>
Android学习笔记(7)————Android中的消息机制
查看>>
重装系统后,硬盘分区丢失的解决办法
查看>>
玩转轻巧型C/C++ IDE之C-Free(配置GCC、Visual C++、Borland C++编译器)
查看>>
利用Delphi编写IE扩展
查看>>
邮箱里边添加自己的网站首页
查看>>
zdnet网站上关注MS技术的记者Foley
查看>>
Enterprise Library 4.1发布新版
查看>>
QTP11的那些事---完整破解方法最终版(测试通过可用)
查看>>