如何在PDF.JS中启用Annotations (替换pdf文本域的内容)
参考链接:https://usefulangle.com/post/94/javascript-pdfjs-enable-annotation-layer
1、添加一个<div>元素来保存注释层
<div id="annotation-layer"></div>
这个div将保存PDF页面的注释数据。PDF将在canvas中呈现。
<canvas id="pdf-canvas"></canvas> <div id="annotation-layer"></div>
2、为注释层添加CSS
#annotation-layer { position: absolute; section { position: absolute; display: flex !important; align-items: center !important; div { white-space: pre; color: black; font-size: 12px !important; line-height: 1 !important; } } }
3、获取PDF注释
在canvas中呈现PDF之后,您需要获得页面的注释数据,然后在注释层元素中呈现该数据。
方法getAnnotations()返回一个Promise,该Promise解析后返回页面的注释数据。render()将呈现注释层div中的数据。
完整代码:
<template>
<div class="pdf-preview-container">
<div
v-for="page in docPages"
:key="page"
ref="container"
class="page-container"
:style="{
height: `${pageHeight}px`,
}"
>
<canvas v-if="renderList.includes(page)" id="pdf-canvas"> </canvas>
<div id="annotation-layer"></div>
</div>
</div>
</template>
<script>
const pdfJS = require('pdfjs-dist/build/pdf')
const pdfjsWorker = require('pdfjs-dist/build/pdf.worker.entry')
pdfJS.GlobalWorkerOptions.workerSrc = pdfjsWorker
export default {
props: {
url: {
type: String,
required: true,
},
data: {
type: Object,
default: () => {},
},
customScroll: {
type: Boolean,
default: false,
},
offsetHeight: {
type: Number,
default: 0,
},
},
data() {
return {
doc: null,
docPages: 0,
currentPage: 0,
pageHeight: 0,
renderList: [],
}
},
watch: {
url: {
immediate: true,
handler() {
this.getPDFFile()
},
},
},
mounted() {
if (!this.customScroll) {
document.addEventListener('scroll', this.scroll)
}
},
beforeDestroy() {
document.removeEventListener('scroll', this.scroll)
},
methods: {
async getPDFFile() {
if (!this.url) return
this.currentPage = 0
const pdf = await pdfJS.getDocument(this.url)
this.doc = pdf
this.docPages = pdf._pdfInfo.numPages
this.$emit('getDocPages', this.docPages)
this.$nextTick(() => {
this.docPages && this.scrollToPage(1)
})
},
scrollToPage(pageNo) {
if (this.currentPage === pageNo) return
this.currentPage = pageNo
const list = []
for (let page = pageNo; page <= this.docPages; page++) {
list.push(page)
}
this.$nextTick(() => {
this.renderList = list
this.renderList.forEach(page => {
this.renderPage(page)
})
})
},
// 渲染page
async renderPage(pageNo) {
const page = await this.doc.getPage(pageNo)
const container = this.$refs.container[pageNo - 1]
if (!container) return
const canvas = container.querySelector('#pdf-canvas')
const annotationLayer = container.querySelector('#annotation-layer')
if (!canvas || canvas.__rendered) return
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio || 1
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1
const ratio = dpr / bsr
const rect = container.getBoundingClientRect()
const viewport = page.getViewport({ scale: 1 })
const width = rect.width
const height = (width / viewport.width) * viewport.height
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
this.pageHeight = height
canvas.height = height * ratio
canvas.width = width * ratio
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
const scale = width / viewport.width
const renderContext = {
canvasContext: ctx,
viewport: page.getViewport({ scale }),
}
page.render(renderContext)
canvas.__rendered = true
const annotations = await page.getAnnotations()
// console.log(pageNo, annotations)
for (const annotation of annotations) {
if (this.data[annotation.fieldName]) {
annotation.fieldValue = this.data[annotation.fieldName]
}
}
annotationLayer.style.width = `${width}px`
annotationLayer.style.height = `${height}px`
annotationLayer.style.left = `${canvas.offsetLeft}px`
annotationLayer.style.top = `${canvas.offsetTop}px`
// Render the annotation layer
pdfJS.AnnotationLayer.render({
viewport: viewport.clone({ dontFlip: true, scale }),
div: annotationLayer,
annotations,
page,
})
},
scroll() {
this.checkRender(document.documentElement)
},
checkRender(el) {
if (!this.pageHeight) return
let scrollTop = el.scrollTop
if (el === document.documentElement) {
scrollTop =
el.scrollTop || window.pageYOffset || document.body.scrollTop
}
let page = Math.floor((scrollTop - this.offsetHeight) / this.pageHeight)
page = Math.max(page, 1)
page = Math.min(page, this.docPages)
this.scrollToPage(page)
},
},
}
</script>
<style lang="scss">
#annotation-layer {
position: absolute;
section {
position: absolute;
display: flex !important;
align-items: center !important;
div {
white-space: pre;
color: black;
font-size: 12px !important;
line-height: 1 !important;
}
}
}
</style>
这里想要吐槽一下pdfjs的文档真是太不完善了,这个还是我研究了好几天源码才发现的功能。希望pdfjs能够把文档完善一下,要不用起来太不方便了o(╥﹏╥)o

浙公网安备 33010602011771号