背景:在页面中,产品总会希望能放一些pdf格式的文件,例如:协议、发票、说明书等
方法一: 使用HTML标签
本质上依赖浏览器内置的 PDF
预览插件,会有黑色背景和工具条等;
- iframe标签
<iframe src="/test.pdf" width="100%" height="400px">
This browser does not support PDFs. Please download the PDF to view it:
<a href="/test.pdf">Download PDF</a>
</iframe>
- embed标签
<embed src="/test.pdf" width="100%" height="400px" />
- object标签
<object
data="/test.pdf"
type="application/pdf"
width="100%"
height="400px"
/>
效果图如下:
注意:(重要)
3个标签都存在浏览器兼容性,并且移动端兼容非常差,使用时需注意用户机型;优点是写法简单,并且支持选中和复制文字;这里更推荐使用iframe,在使用iframe时,iframe属性参考【传送门】,当然还有其他冷门的设置,例如产品不要左侧的菜单和顶部的工具条怎么办?
#page=pagenum, 设置滚动到 pdf 第几页
#zoom=scale,设置缩放比例,缩放值为100表示缩放值为100%
#view=Fit,设置显示区域为适合页面大小
#view=FitH,宽度撑满浏览器窗口,高度自适应
#view=FitV,宽度自适应
#toolbar=1 | 0,打开或关闭工具栏
例如:
<iframe :src=`${pdfUrl}#toolbar=0&view=FitH` width="30%" height="400px">
This browser does not support PDFs. Please download the PDF to view it:
<a href="/test.pdf">Download PDF</a>
</iframe>
效果图:
方法二:使用第三方库
能实现预览pdf的第三方库还是比较多的,但基本上都是基于pdf.js 封装的,使用方法也大同小异,笔者使用过 vue3-pdf
和 pdf-vue3
- pdf-vue3 (www.npmjs.com/package/pdf…)
缺点:包体积较大,部分类型的pdf无法显示
npm i pdf-vue3
<script setup>
import PDF from "pdf-vue3";
</script>
<template>
<PDF src="/demo.pdf" />
<!-- <PDF :src="BASE64" /> -->
<!-- <PDF :src="Uint8Array" /> -->
</template>
效果图:
- vue3-pdfjs (www.npmjs.com/package/vue…)
shims-vue.d.ts
declare module 'vue3-pdfjs/esm';
<script lang="ts">
import { defineComponent, onMounted, reactive, ref } from 'vue';
import { VuePdf, createLoadingTask } from 'vue3-pdfjs/esm';
import { VuePdfPropsType } from 'vue3-pdfjs/components/vue-pdf/vue-pdf-props'; // Prop type definitions can also be imported
import { PDFDocumentProxy } from 'pdfjs-dist/types/src/display/api';
export default defineComponent({
name: 'Home',
components: { VuePdf },
setup() {
const pdfSrc = ref<VuePdfPropsType['src']>('https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf')
const numOfPages = ref(0)
onMounted(() => {
const loadingTask = createLoadingTask(pdfSrc.value)
loadingTask.promise.then((pdf: PDFDocumentProxy) => {
numOfPages.value = pdf.numPages
})
})
return {
pdfSrc,
numOfPages
}
}
});
</script>
<template>
<VuePdf v-for="page in numOfPages" :key="page" :src="pdfSrc" :page="page" />
</template>
效果图:
注意:(重要)
使用这个方案预览发票等文件时,容易出现文字丢失的情况;
解决方案:
PDFJS.getDocument({
url: url,
cMapUrl: "../../static/pdf/cmaps/",
cMapPacked: true
})
参考: www.cnblogs.com/KingJames/p…
我在上面的 vue3-pdfjs 尝试这样发现不好使,
方法三:转成图片展示
转化后无法复制选中文字,并且不好处理多页的情况,暂时没有深入研究;