# PDF预览
# 开始
有一个列表,每一项都是一个pdf,现在需要下载和预览功能。
# 实现预览vue-pdf版本(可能有跨域问题)
<template>
<sweet-modal ref="previewRef" id="preview">
<div class="doc-webhook-pdf">
<BaseLoading :showLoading="onProgress<100"></BaseLoading>
<div class="show-pdf">
<pdf
ref="apiPdf"
v-for="i in numPages"
:key="i"
:page="i"
:src="src">
</pdf>
</div>
</div>
</sweet-modal>
</template>
import pdf from 'vue-pdf/src/vuePdfNoSss';
import BaseLoading from 'component/loading/base-loading';
export default {
components: {
pdf,
BaseLoading,
},
data() {
return {
src: '',
onProgress: 0,
numPages: undefined,
};
},
props: {},
computed: {},
watch: {},
methods: {
// 下载pdf方式 展示pdf
open(id) {
this.clear();
this.$refs.previewRef.open();
try {
this.$http.post("/api/company/bill/download", {
id,
}, {
responseType: 'blob'
}).then((res) => {
let url = this.getObjectURL(res);
this.showPDF(url)
return;
});
} catch (error) {
console.error('error: ', error);
}
},
// 转化 文件流=>URL
getObjectURL(file) {
var binaryData = [];
binaryData.push(file);
let url = null;
if (window.createObjectURL !== undefined) { // basic
url = window.createObjectURL(new Blob(binaryData, {
type: 'application/pdf'
}));
} else if (window.webkitURL !== undefined) { // webkit or chrome
try {
url = window.webkitURL.createObjectURL(new Blob(binaryData, {
type: 'application/pdf'
}));
} catch (error) {}
} else if (window.URL !== undefined) { // mozilla(firefox)
try {
url = window.URL.createObjectURL(new Blob(binaryData, {
type: 'application/pdf'
}));
} catch (error) {}
}
return url;
},
// 展示pdf
showPDF(url) {
setTimeout(() => {
this.src = new pdf.createLoadingTask(url, {
onProgress: this.handleProgress,
});
this.src.promise.then(pdf => {
this.numPages = pdf.numPages;
});
}, 100)
},
// 清除操作,重置参数
clear() {
this.src = ''
this.onProgress = 0
this.numPages = undefined
},
// 进度
handleProgress(e) {
const {
loaded,
total
} = e
this.onProgress = +Number(loaded / total * 100).toFixed(1)
},
// 关闭弹窗
close() {
this.$refs.previewRef.close();
},
},
created() {},
mounted() {}
}
#preview {
.sweet-modal {
max-height: 600px;
overflow-y: scroll;
}
.doc-webhook-pdf {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.show-pdf {
width: 100%;
height: 100%;
}
}
# 实现下载PDF
function downFile(res, fileName) {
const blob = new Blob([res], {
type: `application/pdf;charset=UTF-8`
});
if (window.navigator.msSaveOrOpenBlob) {
// 兼容ie11
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
const url = URL.createObjectURL(blob);
const downloadElement = document.createElement("a");
downloadElement.href = url;
downloadElement.download = fileName;
document.body.appendChild(downloadElement);
downloadElement.click();
downloadElement.remove();
URL.revokeObjectURL(url);
}
}
this.showLoading = true;
try {
this.$http.post("/api/company/bill/download", {
id,
}, {
responseType: 'blob'
}).then((res) => {
this.showLoading = false;
downFile(res, `${bill_no}.pdf`)
return;
});
} catch (error) {
console.error('error: ', error);
}
# 实现预览iframe版本
<template>
<sweet-modal ref="previewRef" id="preview">
<div class="doc-pdf">
<div class="show-pdf">
<iframe :src="src" frameborder="0" style="width: 100%; height: 100%"></iframe>
</div>
</div>
</sweet-modal>
</template>
import BaseLoading from 'component/loading/base-loading';
export default {
components: {
BaseLoading,
},
data() {
return {
src: '',
};
},
props: {},
computed: {},
watch: {},
methods: {
open(id) {
// 通过id获取pdf文件流
// 文件流转URl
// '#toolbar=0'隐藏iframe的控制功能,比如下载、缩放等
this.src = ''
this.$refs.previewRef.open();
try {
this.$http.post("/api/company/bill/download", {
id,
}, {
responseType: 'blob'
}).then((res) => {
let url = URL.createObjectURL(res);
this.src = url + '#toolbar=0'
return;
});
} catch (error) {
console.error('error: ', error);
}
},
/*------------------------ 关闭 ----------------------------*/
close() {
this.$refs.previewRef.close();
},
},
created() {},
mounted() {}
}
#preview {
.sweet-modal {
max-height: 600px;
overflow-y: scroll;
}
.doc-pdf {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.show-pdf {
width: 100%;
height: 500px;
}
}
← mockjs axios 请求超时重发 →