本实现方法后端采用eggjs框架,前端使用vue,样式组件库为ivew,前端使用的curl方法为封装的axios
后端
1. 请求为post
2. controller代码
"use strict";
const fs = require("fs"); //node.js 文件操作对象
const Controller = require("egg").Controller;
class uploadAndDownload extends Controller {
// 下载pdf文件
async downloadPDF({ filePath }, { ctx, userid }) {
if(!filePath){
throw new Error('没有传递filePath参数')
}
// 文件路径,egg的文件路径默认是从项目的文件夹开始的。
// 如果想动态的获取不同的文件,可以根据传递的参数在这里拼出路径
let basicDir = this.app.config.VehicleFileDir; // 配置文件中配置的项目保存文件的绝对路径(指向服务器的某个文件夹,如:'C:\\YDYVehicleFile\\')
// 基础路径 + 请求时携带的文件相对 = 文件在服务器的真实路径
let dirPath = basicDir + filePath;
this.ctx.attachment(dirPath);
// 设置请求头
this.ctx.set('Content-Type', 'application/octet-stream');
// 把数据流赋予body
this.ctx.body = fs.createReadStream(dirPath);
}
}
module.exports = uploadAndDownload;
前端
1. 下载pdf.js
2. pdf.js放置到项目中
文件下载以后进行解压
解压后的文件放到项目中(原则上放到哪个文件夹中无所谓,但是为了使用方便,本人在static文件下新建了一个pdf文件夹进行存放!)
3. vue代码
组件中可以使用iframe或者a标签进行展示,本人选择ifame在页面内采用modal框的形式展示
<Modal v-model="detailModal" width="900">
<p slot="header" style="text-align:center" class="fx__title">
<span>{{modalTitle}}</span>
</p>
<div style="text-align:center;height:500px;poistion:relative;">
<iframe :src="pdfUrl" width="100%" height="99%"></iframe>
</div>
<div slot="footer">
<Button type="default" @click="detailModal = false">关闭</Button>
</div>
</Modal>
方法代码
methods: {
async openDetailModal() {
// pdf文件拼接成pdf.js需要的路径
let fileName = '行政处罚信息.pdf'
let filePath = 'test\\' + fileName
// 请求文件
// 一定要携带后面的type参数!!!!
let content = await this.$curl.post('api/ydyvehicle/downloadPDF', { filePath }, { responseType: 'arraybuffer' })
// 转成blob pdf.js只能识别blob的数据
let blob = new Blob([content])
let url = URL.createObjectURL(blob)
// 修改pdf.js插件需要的路径
// 之所以写 /static/pdf/web/viewer.html ,就是因为我吧pdf.js插件放到了static文件夹下的pdf文件夹
this.pdfUrl = `/static/pdf/web/viewer.html?file=${url}`;
// 打开modal
this.detailModal = true;
},
}
效果