1. PDF component selection
By searching for information, you can find the following solutions, the most mature of which is vue-pdf
1. The iframe can be used not only to browse local static documents, but also to preview the file stream documents returned by the backend
2. vue-pdf is a relatively complete vue preview pdf solution
3. A pdf component packaged by others found on the vueshowpdf network
advantage |
shortcoming | principle | |
iframe/object/embed |
Easy to use, including built-in functions such as page turning, printing, and zooming | Can't disable printing | Embed pdf as a plug-in in these three HTML tags |
vueshowpdf | The style is simple and refreshing, including page turning and zooming functions, and printing can be prohibited | Relevant styles cannot be customized without modifying the source code, there is no progress loading prompt, and a white screen will appear before loading is complete | Based on the underlying pdf.js implementation |
vue-pdf |
Style components can be customized, including loading progress, page turning, interactive elements in the page, etc. | To fix the ratio of width and height, the parent container that wraps the pdf needs to be adjusted as large as possible to display it completely | Implementation based on pdf.js |
To sum it up,
- If you just want to simply embed PDF in the page , using iframe/object/embed is the best choice, it does not require you to write page turning components yourself, and you do not need to adjust the style, and the user experience is good.
- If there is no need to customize the style , it is also very good to use vueshowpdf , and the pop-up UI will look taller.
- If there is a high demand for permission control and style customization , using vue-pdf is the best choice, with complete interfaces and attributes, strong scalability, and high degree of freedom.
2. Iframe usage steps
2.1 Usage and logic
Logic: Set the incomprehensible file stream returned by the backend to responseType="arraybuffer" , then read the returned blob, and then use createObjectURL to read the url
2.2 Code example
<template>
<iframe :src="src" frameborder="0" :style="iframeStyle" />
</template>
<script>
import { mapState } from 'vuex'
import { getNodeObjectData } from '@/modules/viewer/apis/service'
export default {
name: 'pdfPanel',
props: {
node: {
type: Object,
default: () => {}
}
},
data() {
return {
src: ''
}
},
computed: {
...mapState({
innerHeight: (state) => state.viewerStore.setting['innerHeight']
}),
iframeStyle() {
return {
width: '100%',
height: `${this.innerHeight - 130}px`
}
}
},
mounted() {
return getNodeObjectData({
meta_id: this.node.id
})
.then((res) => {
const blob = new Blob([res], { type: 'application/pdf' })
const url = window.URL.createObjectURL(blob)
this.src = url
})
},
methods: {
handleFullScreen() {
window.open(`${this.src}#filename=${this.node.name}`, "_blank")
}
}
}
</script>>
2.3 Detailed explanation with pictures and texts
1. The backend returns a file stream, as follows:
2. Interface request setting responseType="arraybuffer"
export function getNodeObjectData(params) { return axios({ url: `${apiPrefix}/pdf`, method: 'GET', params: params, responseType: 'arraybuffer' }) }