前端实现本地文件上传与预览(PDF格式展示)不走后端接口
实现步骤
第一步:文件选择
使用前端原生
input
上传本地文件,或者是el-upload组件实现文件选择功能,核心在于文件渲染处理。(input只不过可以自定义样式)
<div v-if="!uploaded" v-loading="loading" class="upload_box">
<p @click="openFileSelector()">
<img src="@/assets/上传文件.png"
@dragover.prevent
@drop.prevent="onDrop"
@dragenter.prevent="onDragEnter"
@dragleave.prevent="onDragLeave"
style="padding-left: 30px" />
<input
:id="'file' + title"
type="file"
ref="fileInput"
single
accept=".pdf"
@change="handleFileSelect"
style="display: none" />
<span class="card_text" for="file">请上传本地文件</span>
<span class="card_text" style="font-weight: 400">支持选择、拖拽上传PDF</span>
</p>
</div>
第二步:文件处理
通过
URL.createObjectURL(file)
将本地文件转换为URL进行访问。
<script>
methods: {
//点击上传的方法
openFileSelector() {
// console.log('aaaa');
const filedox = document.getElementById("file" + this.title);
filedox.click();
//this.fileInputRef.click();
},
}
//拖拽的方法
onDrop(event) {
// console.log('ondrop',event)
this.isDragging = false;
const file1 = event.dataTransfer.files[0];
this.uploaded = true;
this.loading = false
if (file1 && file1.type === 'application/pdf') {
//重点是这里将文件转换成本地url地址去访问
const blobUrl = URL.createObjectURL(file1);
// http://192.168.203.213:8080
// console.log('blobUrl',blobUrl)
//将url返回给标签渲染的
this.pdfPreview = blobUrl
}
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (
file.type === "application/pdf" ||
file.type === "application/msword" ||
file.type ===
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
) {
let transform_type_val;
if (files[0].type === "application/pdf") {
if (this.routerType == 'word') {
transform_type_val = 'pdf2word';
file.transform_type = transform_type_val;
} else if (this.routerType == 'excel') {
transform_type_val = 'risk';
file.extract_type = transform_type_val;
}
// console.log('pdf',file.transform_type)
}
this.selectedFiles.push(file);
}
}
// this.uploadFiles();
this.fileInputRef.value = null;
},
//input事件 和 拖拽事件一致
handleFileSelect(event) {
const file1 = event.target.files[0];
if (file1 && file1.type === 'application/pdf') {
this.uploaded = true;
this.loading = false
const blobUrl = URL.createObjectURL(file1);
// http://192.168.203.213:8080
// console.log('blobUrl',blobUrl)
this.pdfPreview = blobUrl
} else {
this.$message.error('仅支持pdf格式文件');
return;
}
// console.log('触犯上传',files);
// for (let i = 0; i < files.length; i++) {
// const file = files[i];
const file = files[0];
const regx = /\.docx$/i;
const regc = /\.doc$/i;
// console.log('file==',file)
if (
file.type === "application/pdf" ||
file.type === "application/msword" ||
file.type === "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ||
regx.test(file.name) || regc.test(file.name)
) {
let transform_type_val;
if (files[0].type === "application/pdf") {
if (this.routerType == 'word') {
transform_type_val = 'pdf2word';
file.transform_type = transform_type_val;
} else if (this.routerType == 'excel') {
transform_type_val = 'risk';
file.extract_type = transform_type_val;
}
// console.log('pdf',file.transform_type)
}
//
this.selectedFiles.push(file);
// console.log('this.selectedF/iles',this.selectedFiles)
}
// }
// this.uploadFiles();
this.fileInputRef.value = null;
},
//走接口的方法
async uploadFiles() {
// console.log('this.selecte/dFiles==',this.selectedFiles)
if (this.selectedFiles.length === 0) {
this.$message.warning("没有选择要上传的文件");
return;
}
const pattern = /http:\/\/oss:/g;
// const pattern = /http:\/\/127.0.0.1:/g;
const formData = new FormData();
let ConvertPDF = false;
// console.log('this.selectedFiles===',this.selectedFiles)
this.selectedFiles.forEach((file) => {
// if(file.transform_type=='pdf2word'){
// ConvertPDF = true
// }
formData.append("file", file);
// console.log('2656251==',)
if (this.routerType == 'word') {
formData.append("transform_type", file.transform_type);
} else if (this.routerType == 'excel') {
formData.append("extract_type", file.extract_type);
}
});
// console.log('didiididi==',)
const aiToken = sessionStorage.getItem("aiToken");
const xtpToken = sessionStorage.getItem("xtpToken");
let apiUrl
if (this.routerType == 'word') {
apiUrl = '/api/v1/transform/create'
// apiUrl = '/api/api/v1/transform/create'
} else if (this.routerType == 'excel') {
apiUrl = '/api/v1/extract/create'
// apiUrl = '/api/api/v1/extract/create'
}
try {
// console.log('上传')
const response = await axios.post(
apiUrl,
formData,
{
headers: {
"Content-Type": "multipart/form-data",
token: aiToken ? aiToken : xtpToken,
},
}
);
this.loading = true
this.$message.success("文件上传成功");
//这应该获得上传好文件的id
// console.log('didi==',response.data.data);
let id = response.data.data.id;
this.$emit('upload', id)
if (!id) {
this.$message.warning('请上传文件')
return
} else {
const fileId = id
if (this.routerType == 'word') {
startTransform({ transform_task_id: fileId }).then((res) => {
// console.log('转换',res);
})
} else if (this.routerType == 'excel') {
startExtract({ extract_task_id: fileId }).then((res) => {
// console.log('转换',res);
}).finally(() => {
console.log("无论如何都执行")
});
}
if (this.routerType == 'word') {
this.$router.push('/wordTable')
} else if (this.routerType == 'excel') {
this.$router.push('/excelTable')
}
}
let src = '';
let errorMsg = '';
// 判断是否转pdf走转pdf的接口
if (ConvertPDF) {
this.timer = setInterval(() => {
detai(id).then((res) => {
src = res.data.pdf_filepath;
errorMsg = res.data.convert_error
if (src) {
const a = src.replace(pattern, `http://10.223.33.105:`);
this.ispdf = true;
this.pdfsrc = a;
this.uploaded = true;
this.loading = false
clearInterval(this.timer)
}
if (errorMsg) {
this.$message.error("文件转换失败" + errorMsg);
}
})
}, 3000);
} else {
//在这获取要展示的pdf地址
// file_url
// console.log('在这获取要展示的pdf地址',response.data)
src = response.data.data.file_url;
// const a = src.replace(pattern, `http://192.168.202.231:`);
const a = src.replace(pattern, `http://10.223.33.105:`);
this.ispdf = true;
this.pdfsrc = a;
this.uploaded = true;
// console.log('pdfsrc==',this.pdfsrc)
}
} catch (error) {
// this.uploaded = true;
this.$message.error("文件上传失败" + error.message);
}
},
// 重新选择
reselect() {
this.$confirm("重新选择比对结果会被清空?", "提示", {
distinguishCancelAndClose: true,
confirmButtonText: "确定",
cancelButtonText: "取消",
})
.then(() => {
this.uploaded = false;
// console.log("dada");
this.selectedFiles = []
this.pdfsrc = ''
this.loading = false
this.$emit('upload', null)
if (this.timer) {
clearInterval(this.timer)
}
})
.catch(() => { });
},
</script>
第三步:实现本地文件渲染的 <embed>
标签
渲染机制:利用浏览器内置的 PDF 插件进行渲染
<embed v-if="pdfPreview" id="pdfPreview" :src="pdfPreview" width="100%" />
效果图