使用pdfjs-dist
package.json
...
"pdfjs-dist": "2.6.347"
...
PdfModal.vue
<template>
<div>
<a-modal
v-if="visible"
class="pdf-modal"
title="导入 PDF 页面"
:visible="visible"
:centered="true"
:mask-closable="false"
:destroy-on-close="true"
:closable="false"
>
<a-spin :spinning="loading">
<!-- 上传pdf文件的组件,拿到pdf的url -->
<pdf-select v-model="pdf" type="doc" upload-text="选择文档" />
</a-spin>
<template #footer>
<a-popconfirm
v-if="loading"
title="正在转换中,确定要取消吗?"
ok-text="确定"
cancel-text="取消"
@confirm="$emit('cancel')"
>
<a-button v-text="取消" />
</a-popconfirm>
<a-button v-else v-text="取消" @click="$emit('cancel')" />
<a-button key="submit" type="primary" :loading="loading" @click="onSubmit">
确认
</a-button>
</template>
</a-modal>
</div>
</template>
<script>
import * as PDFJS from 'pdfjs-dist/build/pdf';
import PDFJSWorker from 'pdfjs-dist/build/pdf.worker.entry.js';
import oss from '@@/utils/oss';
PDFJS.GlobalWorkerOptions.workerSrc = PDFJSWorker;
export default {
name: 'PdfModal',
model: {
prop: 'value',
event: 'change',
},
props: {
value: {
type: String,
default: '',
},
visible: {
type: Boolean,
default: false,
},
},
data() {
return {
pdf: '',
images: [],
loading: false,
};
},
methods: {
async convertToImage() {
const CMapReaderFactory = { url: this.pdf.url };
const loadingTask = PDFJS.getDocument(CMapReaderFactory);
const pdfInfo = await loadingTask.promise;
const files = [];
for (let pageNum = 1; pageNum <= pdfInfo.numPages; pageNum++) {
const canvas = document.createElement('canvas');
const page = await pdfInfo.getPage(pageNum);
const viewport = page.getViewport({ scale: 2 });
const context = canvas.getContext('2d');
canvas.width = viewport.width;
canvas.height = viewport.height;
const renderContext = {
canvasContext: context,
viewport,
};
const renderTask = page.render(renderContext);
await renderTask.promise.then(async () => {
await new Promise((resolve) => {
canvas.toBlob(async (file) => {
file.name = `${this.pdf.name}_page${pageNum}`;
files.push(file);
resolve();
}, 'image/png', 1);
});
});
}
const images = await oss.upload({ files, folder: 'content' });
return images;
},
async onSubmit() {
if (!this.pdf?.url || !this.pdf.url.endsWith('.pdf')) {
this.$message.warning('请选择pdf文件');
return;
}
this.loading = true;
this.images = await this.convertToImage();
this.loading = false;
this.$emit('ok', this.images);
},
},
};
</script>
|