emis-frontend/libs/XdPdf/XdPdf.vue
2024-06-08 15:21:06 +08:00

238 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- <button @click="scalBig">放大</button>
<button @click="scalSmall">缩小</button>
<p>页码:{{ `${pageNo}/${totals.length}` }}</p>
<div class="drag-box" id="dragBox" @scroll="scrollfun($event)">
<el-scrollbar>
<div class="wrapper" id="pdf-container">
<div v-for="item in totals" :id="`page-${item}`" :key="item" class="pdf-box">
<canvas :id="'canvas-pdf-' + item" class="canvas-pdf"></canvas>
</div>
</div>
</el-scrollbar>
</div> -->
<!-- <div ref="pdfContainer">
<div v-loading="loading"></div>
</div> -->
<canvas ref="canvas" v-for="(page, index) in totalPages" :key="index" ></canvas>
</div>
</template>
<script>
// const PDFJS = require('pdfjs-dist')
// PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min')
// import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'
// import 'pdfjs-dist/web/pdf_viewer.css'
// const PDFJS = require('@/static/pdfjs/pdfjs-4.3.136/build/pdf.mjs')
// PDFJS.GlobalWorkerOptions.workerSrc = require('@/static/pdfjs/pdfjs-4.3.136/build/pdf.worker.mjs')
// import * as PDFJS from '../pdfjs-4.3.136/build/pdf.mjs';
// import pdfjsWorker from '../pdfjs-4.3.136/build/pdf.worker.mjs';
const PDFJS = require('@/utils/pdfjs/pdfjs-4.3.136/build/pdf.mjs')
PDFJS.GlobalWorkerOptions.workerSrc = require('@/utils/pdfjs/pdfjs-4.3.136/build/pdf.worker.mjs')
import axios from 'axios';
// PDFJS.GlobalWorkerOptions.workerSrc=pdfjsWorker
export default {
name: 'showPdf',
props: {
pdfUrl:{
type: String,
}
},
data() {
return {
loading:true,
scale: 1.4,
totals: [],
pageNo: 1,
viewHeight: 0,
totalPages: [],
}
},
mounted() {
// this.renderPdf(this.scale)
this.initData();
},
watch: {
pdfUrl(val){
if(pdfUrl){
this.showPdf();
}
}
// scale(val) {
// this.totals = []
// this.renderPdf(val)
// }
},
methods: {
// async previewPDF(pdfUrl) {
// const container = this.$refs.pdfContainer;
// const loadingTask = PDFJS.getDocument(pdfUrl);
// const pdf = await loadingTask.promise;
// const numPages = pdf.numPages;
// for (let i = 1; i <= numPages; i++) {
// const page = await pdf.getPage(i);
// const canvas = document.createElement('canvas');
// container.appendChild(canvas);
// const context = canvas.getContext('2d');
// const viewport = page.getViewport({ scale: 1 });
// canvas.width = viewport.width;
// canvas.height = viewport.height;
// const renderContext = {
// canvasContext: context,
// viewport: viewport
// };
// await page.render(renderContext).promise;
// this.loading = false
// }
// },
async showPdf() {
PDFJS.getDocument(this.pdfUrl).promise.then(pdf => {
this.totalPages = pdf._pdfInfo.numPages
for (let pageIndex = 1; pageIndex <= this.totalPages; pageIndex++) {
pdf.getPage(pageIndex).then(page => {
this.renderPDFPage(page, pageIndex)
})
}
})
},
renderPDFPage(page, pageIndex) {
const canvas = this.$refs.canvas[pageIndex - 1]
const dpiRatio = window.devicePixelRatio || 1
const viewportOptions = { scale: 1, useCurrentScale: false, dontFlip: false, pixelRatio: dpiRatio, isMobile: true }
const viewport = page.getViewport(viewportOptions)
canvas.height = viewport.height
canvas.width = viewport.width
const renderContext = {
canvasContext: canvas.getContext('2d'),
viewport: viewport
}
page.render(renderContext)
},
async downloadAndConvertToUint8Array(pdfUrl) {
// 使用 axios 发送 GET 请求获取 PDF 文件数据
const response = await axios({
url: pdfUrl,
method: 'GET',
responseType: 'arraybuffer', // 设置响应类型为 arraybuffer
});
// 将 arraybuffer 转换为 Uint8Array
const uint8Array = new Uint8Array(response.data);
return uint8Array;
},
renderPdf(scale) {
this.downloadAndConvertToUint8Array(this.pdfUrl)
.then((uint8Array) => {
console.log(uint8Array);
// 现在你可以用这个 Uint8Array 对象进行进一步处理,例如传递给PDF.js库渲染PDF
// 当 PDF 地址为跨域时,pdf 应该已流的形式传输,否则会出现pdf损坏无法展示
PDFJS.getDocument(uint8Array).then(pdf => {
// 得到PDF的总的页数
let totalPage = pdf.numPages
let idName = 'canvas-pdf-'
// 根据总的页数创建相同数量的canvas
this.createCanvas(totalPage, idName)
for (let i = 1; i <= totalPage; i++) {
pdf.getPage(i).then((page) => {
let pageDiv = document.getElementById(`page-${i}`)
let viewport = page.getViewport(scale)
let canvas = document.getElementById(idName + i)
let context = canvas.getContext('2d')
canvas.height = viewport.height
canvas.width = viewport.width
this.viewHeight = viewport.height
let renderContext = {
canvasContext: context,
viewport
}
// 如果你只是展示pdf而不需要复制pdf内容功能,则可以这样写render
// page.render(renderContext) 如果你需要复制则像下面那样写利用text-layer
page.render(renderContext).then(() => {
return page.getTextContent()
}).then((textContent) => {
// 创建文本图层div
const textLayerDiv = document.createElement('div')
textLayerDiv.setAttribute('class', 'textLayer')
// 将文本图层div添加至每页pdf的div中
pageDiv.appendChild(textLayerDiv)
// 创建新的TextLayerBuilder实例
let textLayer = new TextLayerBuilder({
textLayerDiv: textLayerDiv,
pageIndex: page.pageIndex,
viewport: viewport
})
textLayer.setTextContent(textContent)
textLayer.render()
})
})
}
})
})
.catch((error) => {
console.error('Error downloading or converting the PDF:', error);
});
},
createCanvas(totalPages) {
for (let i = 1; i <= totalPages; i++) {
this.totals.push(i)
}
},
// 分页
scrollfun(e) {
let scrollTop = e.target.scrollTop
if (scrollTop === 0) {
this.pageNo = 1
} else {
this.pageNo = Math.ceil(scrollTop / this.viewHeight)
}
},
// 放大
scalBig() {
this.scale = this.scale + 0.1
},
// 缩小
scalSmall() {
if (this.scale > 1.2) {
this.scale = this.scale - 0.1
}
}
}
}
</script>
<style scoped lang="scss">
canvas {
max-width: 100%;
}
.drag-box {
height: 800px;
}
.pdf-box {
position: relative;
}
.el-scrollbar__wrap {
overflow-x: hidden;
}
</style>