cdd-pdf-view
Version:
该组件库基于`pdf-dist`库,能够把 pdf 文件解析成图片放置到指定的容器 dom 中。
173 lines (164 loc) • 4.53 kB
text/typescript
///<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)
})
}
})
})
}
}