vue2.6附件预览及下载
vue2.6附件预览及下载
用户上传了自己的附件信息后,在pc端需要支持预览及下载。上传的文件格式可能有多种。常见的有:png、img、docx、doc、pdf、xlsx、xls……。需要同时支持多种文件类型的预览及下载。
文件预览
pdf/docx/xlsx预览
在开始使用时,使用过pdfjs
、embed
、iframe
去预览pdf,但是改动成本较大。在本项目中的文件都不会过大,并且只需要基础预览即可。最终使用了vue-office 进行基础附件预览。
使用步骤
-
安装对应依赖
npm install @vue-office/docx vue-demi npm install @vue-office/excel vue-demi npm install @vue-office/pdf vue-demi
如果vue<=2.6,则需要额外安装
npm install @vue/composition-api
-
在页面中引入并使用
<template>
<pdf v-if="fileType === 'pdf'" :src="url" />
<docx v-if="fileType === 'docx'" :src="url" />
<excel v-if="fileType === 'xlsx'" :src="url" />
</div>
</template>
<script>
import pdf from '@vue-office/pdf'
import docx from '@vue-office/docx'
import excel from '@vue-office/excel'
export default {
components: { pdf, docx, excel }
}
// 省略了prop参数
……
</script>
image/* 预览图片
对于图片的展示可以直接使用img
标签,但如果我们需要对图片进行放大,旋转等操作,则需要借助第三方组件,可以使用element自带的预览或者v-viewer
。
v-viewer的使用
参考链接
- 安装依赖
npm install viewerjs
- 全局引入或局部引入
// 局部引入 const ViewerDom = document.getElementById('#imgBox'); const viewer = new Viewer(ViewerDom, { // 配置项省略}); // main.js中全局引入 import 'viewerjs/dist/viewer.css' import VueViewer from 'v-viewer Vue.use(VueViewer)
doc/xls文件预览
vue-office底层基于docx.js解析器,仅支持遵循Office Open XML标准的.docx格式,而.doc属于二进制格式(OLE2复合文档),解析复杂度高且需专门解码库。要实现.doc预览,需通过格式转换或专用解析器两种路径。
可操作的方案如下:
方案 | 开发成本 | 维护成本 | 效果质量 | 适用场景 |
---|---|---|---|---|
后端转换+前端预览 | 中 | 低 | ★★★★★ | 企业级生产环境 |
Mammoth.js前端解析 | 低 | 高 | ★★☆☆☆ | 简单文档临时预览 |
OnlyOffice集成 | 高 | 中 | ★★★★★ | 需要完整编辑功能 |
微软官方嵌入 | 中 | 低 | ★★★★★ | 已有Azure生态集成 |
从开发成本上考虑,可以直接使用微软官提供的在线预览的方式。直接通过iframe嵌入微软的预览地址。
使用步骤
- 处理doc或xls的链接地址
computed:{
officeViewerUrl() {
return `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
this.url
)}`
},
}
- 通过iframe直接嵌入该链接
<!-- ✅ 新增微软在线预览处理 -->
<template>
<iframe
v-if="isLowFileType"
:src="officeViewerUrl"
class="office-iframe"
frameborder="0"
></iframe>
</template>
<style scoped lang="less">
.file-wrapper {
overflow: auto;
// ✅ 添加iframe样式
.office-iframe {
width: 100%;
height: 80vh;
min-height: 600px;
border: 1px solid #eee;
border-radius: 4px;
}
}
</style>
总结: 对于
pdf/xlsx/docx
,我们直接使用vue-office
进行预览;图片可以使用v-viewer
预览;兼容低版本的doc/xls
,则使用微软官方提供的在线预览方案。将上述代码整合即为我们项目的附件预览组件。
附件下载
前提:现在有一个可以直接访问的在线链接地址,以及文件的名称。文件类型需要我们根据名称取获取,类型可能为之前的上传类型,比如pdf、docx、xlsx、png、jpg……
刚开始使用的是<a>
标签,并将href设置为链接地址,但是这样存在一个问题。图片类型的会直接下载,非图片类型比如pdf,则会打开新的标签页进行预览,无法直接下载。用户可能上传的有多个附件,并且附件类型可能不同。因此我们展示一个链接以及一个按钮,分别用于预览和下载。
下载按钮实现
function handleDownload(loadLink, name) {
try {
// 创建隐藏的下载链接
const link = document.createElement('a')
link.style.display = 'none'
// 处理跨域下载
const response = await fetch(loadLink)
const blob = await response.blob()
const objectURL = URL.createObjectURL(blob)
link.href = objectURL
link.download = name // 强制使用指定文件名
document.body.appendChild(link)
link.click()
// 清理资源
URL.revokeObjectURL(objectURL)
document.body.removeChild(link)
} catch (error) {
this.$message.error(`下载失败: ${error.message}`)
}
}
预览按钮实现
function handlePreview(loadLink, name) {
// 其他类型使用浏览器默认行为
const link = document.createElement("a");
link.href = loadLink;
link.target = "_blank";
link.rel = "noopener noreferrer";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
链接展示
<div
v-for="item in attachList"
:key="item.id"
>
<a
target="_blank"
rel="noopener noreferrer"
@click.prevent="clickFileLink(item.url, item.name)"
>
{{ item.name }}
</a>
// 为图片时不展示下载按钮
<a-button
v-if="!$utils.isImage(item.name)"
type="link"
size="small"
@click="handleDownload(item.url, item.name)"
>
下载附件
</a-button>
</div>
总结
在本文中,我们详细介绍了如何在 Vue 2.6 项目中实现多种文件类型的预览和下载功能。通过整合不同的技术和工具,我们成功解决了不同类型文件的预览需求,并提供了一个通用的下载解决方案。
小知识
a标签的下载行为取决于以下因素
因素 | 触发下载的条件 | 触发打开的条件 | 典型场景示例 |
---|---|---|---|
服务器响应头 | Content-Disposition: attachment | Content-Disposition: inline | 强制用户下载财务报告.docx |
HTML属性 | 存在 download 属性(且同源) | 无 download 属性 | <a href="file.pdf" download> |
文件类型 | 浏览器无法渲染的格式(.zip/.exe) | 浏览器可渲染格式(.pdf/.jpg) | .txt 文本直接展示,.apk 触发下载 |
跨域限制 | 跨域文件且未配置 CORS | 同源文件 | CDN 上的图片直接打开,跨域 Excel 被拦截 |
浏览器设置 | 用户手动设置「始终下载此类文件」 | 默认处理策略 | 用户强制所有 PDF 自动下载 |
浏览器兼容性 | Safari 对部分格式的保守策略 | Chrome 对 PDF 的内置预览 | iOS 上 .docx 可能直接下载 |