因爲公司業務的開發須要,須要實如今electron上實現PDF的在線預覽功能。electron 3.x版本後就不在支持PDF的預覽功能了,官方給的解釋是因爲人手不夠將再也不支持PDF預覽功能(也是醉了),在通過一番調研結合大佬們的經驗實現了PDF的在在線預覽功能javascript
下載pdfjs-distcss
將下好的文件放入static文件目錄下html
在electron的主線程中經過渲染線程與主線程之間的通訊獲取viewer.html文件位置vue
// 監聽獲取viewer.html文件位置、
function getUrl(win) {
const filePath = process.env.NODE_ENV === 'development' ? `${__static}\\pdfjs\\web\\viewer.html` : path.resolve(__dirname, '../../../static/pdfjs/web/viewer.html')
win.webContents.send('recieve', filePath)
}
// pdf預覽獲取viewer.html文件位置
ipcMain.on('getUrl', () => getUrl(win))
複製代碼
在pdf.vue中寫java
<template>
<iframe
:src="base + '?file=' + url"
:width="width"
:height="height"
class="iframe-placeholder"></iframe>
</template>
<script>
import { ipcRenderer } from 'electron' // eslint-disable-line
export default {
props: {
url: {
type: String,
default: '',
},
width: {
type: Number,
default: 750
},
height: {
type: Number,
default: 600
},
},
data() {
return {
preview: false,
base: '',
}
},
computed: {
// 講義文件名
name() {
const uri = decodeURI(this.url)
const arr = uri.split('/')
const len = arr.length
return arr[len - 1]
},
},
created() {
// 獲取viewer.html的位置
ipcRenderer.send('getUrl')
},
mounted() {
ipcRenderer.on('recieve', (e, arg) => {
console.log('文件路徑', arg)
this.base = arg
})
}
}
</script>
<style lang="scss" scoped>
.wrapper {
.info {
width: 200px;
}
.iframe-placeholder {
background: url('../../../assets/loading.svg') no-repeat 50% 50%;
}
}
</style>
複製代碼
在須要引入的地方引用便可webpack
問題git
樣式比較醜,可是能夠實現PDF的分頁和打印的功能,且在打完包後文件比較大web
下載npm pdfjs-dist 包npm
// npm的下載方式
npm i pdfjs-dist
// yarn 的下載方式
yarn add pdfjs-dist
複製代碼
在webpack的配置中寫入canvas
entry: {
renderer: path.join(__dirname, '../src/renderer/main.js'),
'pdf.worker': 'pdfjs-dist/build/pdf.worker.entry',
},
複製代碼
在pdf.vue中寫入
<template>
<el-dialog
:visible.sync="pdfjsView"
title=""
width="55%"
class="cpdf"
append-to-body
@close="pdfurl = null">
<div v-loading="loading" v-if="pdfurl" class="center" style="height:600px">
<canvas v-for="data in canvasData" :key="data" :id="'the-canvas-'+data" class="canvasstyle"></canvas>
</div>
<div v-else style="font-size:18px;text-align:center;font-weight:900">
沒有PDF文件能夠預覽
</div>
<span slot="footer">
<el-button @click="pdfjsView = false">取 消</el-button>
<el-button type="primary" @click="pdfjsView = false">確 定</el-button>
</span>
</el-dialog>
</template>
<script type="text/ecmascript-6">
import PDFJS from 'pdfjs-dist'
export default {
name: 'CPdf',
components: {},
data() {
return {
pdfDoc: null, // pdfjs 生成的對象
pageNum: 1, //
pageRendering: false,
pageNumPending: null,
scale: 1.2, // 放大倍數
page_num: 0, // 當前頁數
page_count: 0, // 總頁數
maxscale: 2, // 最大放大倍數
minscale: 0.8, // 最小放大倍數
canvasData: [],
pdfjsView: false,
pdfurl: null,
loading: false
}
},
methods: {
renderPage(num) {
// 渲染pdf
const vm = this
this.pageRendering = true
const canvas = document.getElementById(`the-canvas-${num}`)
// Using promise to fetch the page
this.pdfDoc.getPage(num).then((page) => {
const viewport = page.getViewport(vm.scale)
// alert(vm.canvas.height)
canvas.height = viewport.height
canvas.width = viewport.width
// Render PDF page into canvas context
const renderContext = {
// canvasContext: vm.ctx,
canvasContext: canvas.getContext('2d'),
viewport
}
const renderTask = page.render(renderContext)
// Wait for rendering to finish
renderTask.promise.then(() => {
vm.pageRendering = false
if (vm.pageNumPending !== null) {
// New page rendering is pending
vm.renderPage(vm.pageNumPending)
vm.pageNumPending = null
}
})
})
vm.page_num = vm.pageNum
},
getUrl(url) {
this.pdfurl = url
this.pdfjsView = true
this.showPDf()
},
showPDf() {
const vm = this
this.loading = true
vm.canvasData = []
// PDFJS.workerSrc = '../../../static/PDF/pdf.worker.min.js'
PDFJS.getDocument(vm.pdfurl)
.then((pdfDoc_) => {
// 初始化pdf
vm.pdfDoc = pdfDoc_
vm.page_count = vm.pdfDoc.numPages
for (let i = 0; i < vm.page_count; i += 1) {
vm.canvasData.push(i + 1)
}
return pdfDoc_
})
.then((pdfDoc_) => {
// 初始化pdf
vm.pdfDoc = pdfDoc_
vm.page_count = vm.pdfDoc.numPages
for (let i = 0; i < vm.page_count; i += 1) {
vm.renderPage(i + 1)
}
vm.loading = false
})
}
},
computed: {},
mounted() {}
}
</script>
<style lang="scss" scoped type="text/css">
.cpdf {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
display: flex;
justify-content: center;
align-items: center;
.center {
text-align: center;
height: 100%;
overflow: auto;
padding-top: 20px;
.contor {
margin-bottom: 10px;
}
}
.page-foot {
position: fixed;
left: 0px;
bottom: 0px;
width: 100%;
height: 56px;
line-height: 56px;
background-color: #fff;
text-align: center;
z-index: 10;
.foot-button {
display: inline-block;
height: 56px;
position: relative;
top: -22px;
left: 20px;
}
}
}
</style>
複製代碼
在須要引入的地方引入便可
問題
加載 npm i electron-pdf ,因爲這種方法會致使新建窗口,故沒有作實驗