前言:在项目中遇到了一个后端给过来的base64 格式的pdf文件,要求前端在h5端预览
踩坑方案一:只能支持web浏览器,不能在手机的壳子中展示
上代码:
const base64Data = '你的数据base64编码';
const byteCharacters = atob(base64Data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: 'application/pdf' });
const fileUrl = URL.createObjectURL(blob);
<template>
<iframe src={fileUrl} width="100%" height="500px"></iframe>
<template/>
最终解决方案 : 使用 ddfjs 插件
- 安装 pdfjs
yarn add pdfjs-dist - 使用 新建一个 PdfView.vue 组件
<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue'
import * as pdfjsLib from 'pdfjs-dist'
/**
* 这里要注意 一定要 将 node_modules/pdfjs-dist/build/pdf.worker.min.mjs
* 复制一份到public/pdf.worker.min.mjs
*/
pdfjsLib.GlobalWorkerOptions.workerSrc =
'/pdf.worker.min.mjs'
export default defineComponent({
name: 'PdfViewer',
props: {
base64Pdf: {
type: String,
required: true
}
},
setup(props) {
const pdfContainer = ref<HTMLDivElement | null>(null)
onMounted(async () => {
if (pdfContainer.value && props.base64Pdf) {
try {
const loadingTask = pdfjsLib.getDocument({ data: atob(props.base64Pdf) })
const pdfDocument = await loadingTask.promise
for (let pageNum = 1; pageNum <= pdfDocument.numPages; pageNum++) {
const page = await pdfDocument.getPage(pageNum)
const viewport = page.getViewport({ scale: 1.5 })
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
if (context) {
canvas.height = viewport.height
canvas.width = viewport.width
await page.render({ canvasContext: context, viewport }).promise
pdfContainer.value.appendChild(canvas)
}
}
} catch (error) {
console.error('Error rendering PDF:', error)
}
}
})
return { pdfContainer }
}
})
</script>
<template>
<div ref="pdfContainer" class="pdf-container"></div>
</template>
<style scoped>
.pdf-container {
display: flex;
flex-direction: column;
gap: 16px;
}
canvas {
border: 1px solid #ddd;
}
</style>
- 使用组件
<script setup lang="ts">
// demoData 为base64 string
import { demoData } from './components/data'
import PdfViewer from './components/pdfView.vue'
</script>
<template>
<div class="pdf -page">
<PdfViewer :base64Pdf="demoData" />
</div>
</template>
<style lang="scss" scoped></style>