UNPKG

cdd-pdf-view

Version:

该组件库基于`pdf-dist`库,能够把 pdf 文件解析成图片放置到指定的容器 dom 中。

173 lines (164 loc) 4.53 kB
///<reference path='../../index.d.ts'/> import pdfjs from "pdfjs-dist" import {orderBy} from "lodash" // import worker from "pdfjs-dist/lib/pdf.worker.js" // pdfjs.GlobalWorkerOptions.workerSrc = '' // import 'pdfjs-dist/build/pdf.worker' /** * 解析pdf类 * @class CddPdf */ export default class CddPdf { /**要预览的文件,一般用于本地文件转换 */ file?: File /**网络pdf文件地址,仅支持流下载的接口 */ url?: string /**解析后的图片地址 */ imgs: string[] = [] /**Promise属性 */ promise?: Promise<any> /**Blob url与否,如果不是则是objectUrl */ isBlobUrl?: boolean = false /**配置选项 */ options = { /**伸缩质量 */ scale: 2 } /** * 构造函数 * @constructor 构造函数 * @param {Object} params 参数 * @param params.options 配置 */ constructor (params: { /**文件 */ file?: File, /**流地址 */ url?: string, /**是否是blob url */ isBlobUrl?: boolean, /**选项 */ options?: { /**放大质量,默认是2 */ scale?: number } }) { if (!params) { throw new Error(`缺少参数 file 或者 url`) } else { this.file = params.file this.url = params.url this.isBlobUrl = params.isBlobUrl || this.isBlobUrl } // 如果存在设置 if (params.options) { this.options = Object.assign({}, this.options, params.options) } this.promise = this.init() } /**获取pdf */ static GetPdf (params: { file?: File, url?: string, isBlobUrl?: boolean, options?: { scale?: number } }) { return new CddPdf(params).promise } /**初始化数据 */ async init () { // 获取数据 const data = await this.getData() //转化成图片 this.imgs = orderBy(await this.parsePdf(data) as any, [ 'pageNumber' ]) console.log(`over`, this.imgs) return this // 渲染pdf } /**获取数据 */ getData () { return new Promise((reso, reg) => { if (this.file) { const reader = new FileReader() reader.onload = (e: any) => reso(e.target.result) reader.readAsDataURL(this.file) } else if (this.url) { reso(this.fetchFile(this.url)) } }) } /**fetc获取文件内容 */ fetchFile (url: string) { return new Promise((reso, rej) => { if (url && url.startsWith('http')) { /**获取数据 */ fetch(url).then(async (res) => { const blob = await res.blob() reso(URL.createObjectURL(blob)) }) } else { reso(url) } }) } /**解析pdf文件 */ async parsePdf (file: any) { try { return new Promise((reso, rej) => { const loadingTask = pdfjs.getDocument(file) const arr: any[] = [] let count = 0 if (loadingTask.promise) { loadingTask.promise.then(pdf => { if (pdf && pdf.numPages) { for (let i = 1; i <= pdf.numPages; i++) { pdf.getPage(i).then(async (page) => { arr.push(await this.renderPage(page)) count++ if (count === pdf.numPages) { reso(arr) } }) } } }) } }) } catch (error) { console.error(`渲染出错`, error) } } /**渲染页面 */ renderPage (page: any) { return new Promise((reso, rej) => { const viewport = page.getViewport({scale: this.options.scale}) const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width const renderContext = { canvasContext: ctx, viewport: viewport } //进行渲染 page.render(renderContext).promise.then((res: any) => { if (this.isBlobUrl) { canvas.toBlob((blob) => { reso({ pageNumber: page.pageNumber, // value: canvas.toDataURL('image/png', 1) value: URL.createObjectURL(blob) }) }, 'image/png', 1) } else { reso({ pageNumber: page.pageNumber, value: canvas.toDataURL('image/png', 1) }) } }) }) } }