1.安装
npm install pdfjs-dist@2.2.228 --save
2.使用
<template>
<div class="document">
<div class="document-content">
<div class="card-container">
<div class="document-card">
<a-upload
list-type="picture-card"
:show-upload-list="false"
:before-upload="beforeUpload"
:customRequest="customRequest"
accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf"
>
<div>
<a-icon type="plus" />
<div class="ant-upload-text">导入文档</div>
</div>
</a-upload>
</div>
<div
class="document-card"
v-for="item in uploadDocumentList"
:key="item.id"
@click="documentClick(item.name, item.loading)"
>
<div class="loading" v-show="item.loading">
<span><span class="load-icon"></span>识别中</span>
</div>
<div class="img-wrapper">
<canvas class="pdfCanvas" :id="`pdfCanvas${item.id}`"></canvas>
</div>
<p :title="item.name">{{ item.name }}</p>
</div>
<div
class="document-card"
v-for="item in documentList"
:key="`document${item.id}`"
@click="documentClick(item.name, item.loading)"
>
<div class="img-wrapper">
<img :src="item.imgSrc" />
</div>
<p :title="item.name">{{ item.name }}</p>
<div class="opr-btn">
<a-tooltip>
<template slot="title">编辑</template>
<span class="edit-btn"></span>
</a-tooltip>
<a-tooltip>
<template slot="title">发布</template>
<span class="publish-btn"></span>
</a-tooltip>
<a-tooltip>
<template slot="title">删除</template>
<span class="delete-btn"></span>
</a-tooltip>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
// const pdfjsLib = require('pdfjs-dist')
// pdfjsLib.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min')
import pdfjsLib from 'pdfjs-dist'
const list = [
{
id: 1,
name: 'AIGC与数字李生:引爆生产力革命',
imgSrc: require('@/assets/demo/document1.png')
},
{
id: 2,
name: '软件研发技术评审管理办法',
imgSrc: require('@/assets/demo/document2.png')
},
{
id: 3,
name: '2019新一代人工智能产业白皮书一主要应用场景研判',
imgSrc: require('@/assets/demo/document3.png')
}
]
export default {
name: 'DocumentList',
data() {
return {
documentList: list.slice(0, 2),
uploadDocumentList: []
}
},
methods: {
beforeUpload(file) {
console.log('file', file.name)
// 检查文件类型是否为PDF
if (file.type === 'application/pdf') {
const id = +new Date() + (Math.random() * 1000).toFixed(0)
this.uploadDocumentList.unshift({
name: file.name,
id: id,
loading: true
})
setTimeout(() => {
const pdfCanvas = document.getElementById(`pdfCanvas${id}`)
const ctx = pdfCanvas.getContext('2d')
const reader = new FileReader()
reader.onload = (e) => {
const pdfData = new Uint8Array(e.target.result)
console.log('pdfData', pdfData)
// 使用PDF.js加载PDF文件
pdfjsLib
.getDocument({ data: pdfData })
.promise.then((pdf) => {
console.log('pdf', pdf)
// 获取第一页
return pdf.getPage(1)
})
.then((page) => {
const scale = 1.5
const viewport = page.getViewport({ scale })
// 设置画布大小
pdfCanvas.width = viewport.width
pdfCanvas.height = viewport.height
const renderContext = {
canvasContext: ctx,
viewport: viewport
}
// 渲染第一页到画布上
page.render(renderContext).promise.then(() => {
console.log('第一页渲染完成')
this.uploadDocumentList[0].loading = false
})
})
}
reader.readAsArrayBuffer(file)
return true
}, 2000)
} else {
this.$warning('请选择PDF文件')
}
},
// 自定义上传
customRequest(file) {
console.log('file', file)
},
documentClick(name, loading) {
if (!loading) {
this.$router.push({
path: '/document/detail',
query: {
title: name
}
})
}
}
}
}
</script>
<style lang="less" scoped>
.document {
width: 100%;
height: 100%;
.document-content {
display: flex;
height: 100%;
.card-container {
width: 100%;
padding-left: 25px;
padding-top: 20px;
overflow: auto;
.document-card {
width: calc(25% - 20px);
height: 200px;
margin-right: 20px;
margin-bottom: 20px;
float: left;
position: relative;
background: #f7f8fa;
border: 1px dashed #e5e6ec;
border-radius: 8px;
position: relative;
cursor: pointer;
& + .document-card {
border-style: solid;
}
:deep .ant-upload-picture-card-wrapper {
width: 100%;
height: 100%;
.ant-upload.ant-upload-select-picture-card {
margin-right: 0;
margin-bottom: 0;
background: inherit;
border: none;
width: 100%;
height: 100%;
.ant-upload-text {
color: #1d2129;
line-height: 20px;
}
}
}
.loading {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
color: @primary-color;
font-weight: bold;
.load-icon {
margin-right: 5px;
width: 44px;
height: 44px;
display: inline-block;
vertical-align: middle;
background: url('~@/assets/demo/loading.png') no-repeat center center;
background-size: 100% 100%;
animation: rotateInfinity 1.5s linear infinite;
}
}
.img-wrapper {
height: 100%;
border-radius: 8px;
overflow: hidden;
img {
width: 100%;
min-height: 100%;
}
}
p {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 0;
padding: 0 20px;
font-size: 14px;
color: #fff;
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 48px;
line-height: 48px;
border-radius: 0 0 8px 8px;
background: rgba(0, 0, 0, 0.5);
}
.pdfCanvas {
width: 100%;
height: 100%;
}
.opr-btn {
position: absolute;
top: 16px;
right: 16px;
display: flex;
z-index: 2;
span {
display: block;
width: 22px;
height: 22px;
border-radius: 50%;
& + span {
margin-left: 4px;
}
&.edit-btn {
background: url('~@/assets/demo/edit.png') no-repeat center center;
background-size: 100% 100%;
}
&.publish-btn {
background: url('~@/assets/demo/publish.png') no-repeat center center;
background-size: 100% 100%;
}
&.delete-btn {
background: url('~@/assets/demo/delete.png') no-repeat center center;
background-size: 100% 100%;
}
}
}
}
}
}
}
@keyframes rotateInfinity {
0% {
transform: rotate(0de);
}
100% {
transform: rotate(180deg);
}
}
</style>