如果你正在使用Fabric.js这个强大的JavaScript库来构建你的图形界面,那么你可能会遇到加载pdf文件的需求,其实我看fabric的源码里面支持的文件后缀是包括pdf的,不知道怎么回事pdf不能直接加载。本文通过结合pdfjs实现加载和缩放,附代码。
实现思路:
将pdf用pdfjs解析成canvas,就可以被fabric加载了。
实现步骤:
1、安装pdfjs-dist,这里我安装的是以下版本
npm install pdfjs-dist@^2.5.207
2、在文件中引入,最好是将解析过程封装成工具放在一个单独的文件夹里,我这里是放在utils里面的pdfToCanvas.js里的。
import { fabric } from 'fabric'
import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker // 这个一定不要忘了
3、解析pdf
/**
pdfData:pdf地址,
zoom:缩放比例,
divWidth:父盒子尺寸
*/
async function printPDF (pdfData, zoom, divWidth) {
pageurl = pdfData
// Using DocumentInitParameters object to load binary data.
let loadingTask = pdfjs.getDocument({
url: pdfData
})
return loadingTask.promise
.then((pdf) => {
return pdf.getPage(1) // 因为我只需要第1页
.then((page) => {
pagedata = page
return pdfTocanvas(page, zoom, divWidth)
})
})
}
4、转为canvas
async function pdfTocanvas (page, zoom, divWidth) {
if(divWidth) {
let pageWdith = Math.min(page._pageInfo.view[3], page._pageInfo.view[2])
initZoom = divWidth / pageWdith - 1
}
let viewport = page.getViewport({
scale: zoom + initZoom
})
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
canvas.height = viewport.height
canvas.width = viewport.width
const renderContext = {
canvasContext: context,
viewport: viewport,
intent: 'speed'
}
viewport = null
const renderTask = page.render(renderContext)
return renderTask.promise.then(() => canvas)
}
5、导出pdfToCanvas方法
export async function pdfToCanvas (pdfData, zoom, divWidth) {
// 判断是否是首次加载,如果已经加载过了就不需要重新解析只需要转换就可以了
let c = pageurl === pdfData ? await pdfTocanvas(pagedata, zoom, divWidth) : (await printPDF(pdfData, zoom,divWidth))
let img = new fabric.Image(c, {
originX: 'left',
originY: 'top',
scaleX: 1 / (zoom + initZoom),
scaleY: 1 / (zoom + initZoom)
})
return {img,zoom:zoom + initZoom}
}
6、在页面使用时引用
import { pdfToCanvas } from '@/utils/pdfToCanvas.js'
pdfToImage(src, 1, this.initialWidth).then(({img,zoom}) => {
canvas.setBackgroundImage(img)
this.canvasMessage.width = img.width
this.canvasMessage.height = img.height
this.pdfZoom = zoom
this.setCanvasZise()
})
这只是基于vue2的用法,如果你是vue3可能会由于版本不匹配而报错,后面有时间我会更新一期在vue3中的用法。