vue3 前端文件预览实现

一 背景

公司制作在线文件预览库,可接受不能预览doc、ppt;

复制代码
1)图片采用:element-plus的 el-image-viewer
2)vue-office 系列组件可预览 :pdf、docx、excel(xls、xlsx、csv)、pptx
3)bestofdview:预览ofd
4)dplayer 预览音频:mp4,这别后台会校验mp4 前 200 KB 内 有 moov(可边加载边播放)

其他介绍
txt:直接读取内容:放入网页显示(本文章不做介绍)
html:不推荐预览,加载script 可能会攻击你的网站

这里档案库禁止 doc、ppt 上传,除了上面能预览的档案外,档案库还允许上传安全的压缩包类型;

注:为了保证文件的防止传播性,这边后台会为每次预览生成一个临时token,且预览地址会携带该参数;后台会校验token 合法、短时间有效、甚至是单次有效,防止通过预览地址下载到原文件

1.1 预览效果

1 图片:注:不一定要点击图片显示,也可点击按钮直接渲染:el-image-viewer 组件

地址中图片预览 ,https://element-plus.org/zh-CN/component/image
2 pdf、office系列

地址中的:演示效果,https://github.com/501351981/vue-office
3 ofd

地址中的:在线预览地址,https://github.com/besthqs/bestofdview
4 媒体

地址中的媒体:https://github.com/DIYgod/DPlayer

1.2 安装依赖

复制代码
# 预览图片 
pnpm install element-plus

# 预览pdf
pnpm install  @vue-office/pdf
# 预览 docx
pnpm install  @vue-office/docx
# 预览 xls、xlsx
pnpm install  @vue-office/excel
# 预览ppt
pnpm install  @vue-office/pptx

# 预览 ofd
pnpm install  bestofdview

# 预览mp4
pnpm install dplayer

二 实现介绍

2.1 图片

element-plus 版本 2.9.9 ,组件名imageDialog

效果,地址中的:图片预览 ,https://element-plus.org/zh-CN/component/image
注:不一定要点击图片显示,也可点击按钮直接渲染:el-image-viewer 组件

复制代码
<template>
<el-watermark v-if="imgViewerVisible" :content="watermarkContent" :font="watermarkFont " :z-index="3100"
                style="position: fixed; inset: 0; z-index: 3000">
    <el-image-viewer
        :url-list="[fileUrl]"
        :initial-index="0"
        :z-index="3000"
        @close="closeDialog"
    />
  </el-watermark>
</template>
<script setup>
const
// 图片预览是否显示
const imgViewerVisible = ref(false)
// 文件url 
const fileUrl = ref()

const watermarkContent = ref('水印')
const watermarkFont  = ref({
      color: 'rgba(0, 0, 0, 0.2)',
      fontSize: 16,
      fontWeight: 'bold',
      fontFamily: 'sans-serif'
 })
 
// 关闭窗口
const closeDialog = () => {
  dialogVisible.value = false;
  imgViewerVisible.value = false;

  fileUrl.value = '';
}

const open = async (url ) => {
fileUrl.value = url
imgViewerVisible.value = true
})

2.2 pdf预览

PdfView.vue 官方样例:https://github.com/501351981/vue-office
注:options 传空即可,这里禁用多线程加载是为了保护服务器

复制代码
<template>
  <vue-office-pdf
      :src="fileUrl"
      style="flex: 1;height: 0"
      :options="options"
      @rendered="rendered" @error="handleError"
  />
</template>

<script setup>
//引入VueOfficePdf组件
import VueOfficePdf from '@vue-office/pdf'

const emit = defineEmits(['error'])

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  }
})

let options = {
  // 禁用 range
  disableRange: true,
  // 禁用流式加载
  disableStream: true,
  // 禁用自动预取
  disableAutoFetch: true,
}

const rendered = () => {
  console.log("渲染完成")
}

const handleError = (error) => {
  emit('error', error)
}
</script>

2.3 docx预览

DocView.vue 官方样例:https://github.com/501351981/vue-office

复制代码
<template>
  <vue-office-docx
      :src="fileUrl"
      style="flex: 1;height: 0"
      @rendered="rendered" @error="handleError"
  />
</template>

<script setup>
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'

const emit = defineEmits(['error'])

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  }
})

const rendered = () => {
  console.log("渲染完成")
}

const handleError = (error) => {
  emit('error', error)
}
</script>

2.4 xlxs、csv 预览

ExcelView.vue 官方样例:https://github.com/501351981/vue-office

复制代码
<template>
  <vue-office-excel
      :src="fileUrl"
      :options="{xls: xls}"
      style="height: 100vh;"
      @rendered="rendered" @error="handleError"
  />
</template>

<script setup>
//引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'

const emit = defineEmits(['error'])

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  },
  // 是否是xls
  xls: {
    type: Boolean,
    default: false
  }
})

const rendered = () => {
  console.log("渲染完成")
}

const handleError = (error) => {
  emit('error', error)
}
</script>

2.5 pptx 预览

PptxView.vue 官方样例:https://github.com/501351981/vue-office

复制代码
<template>
  <vue-office-pptx
      :src="fileUrl"
      style="flex: 1;height: 0"
      @rendered="rendered" @error="handleError"
  />
</template>
<script setup>
//引入VueOfficePptx组件
import VueOfficePptx from '@vue-office/pptx'

const emit = defineEmits(['error'])

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  }
})

const rendered = () => {
  console.log("渲染完成")
}

const handleError = (error) => {
  emit('error', error)
}
</script>

2.6 ofd 预览

OfdView.vue 官方样例:https://github.com/besthqs/bestofdview

复制代码
<template>
  <div class="ofd-view-container">
    <OfdView
      :showOpenFileButton="true"
      :ofdLink="fileUrl"
    ></OfdView>
  </div>
</template>
<script setup>
import { OfdView } from "bestofdview";
import "bestofdview/dist/style.css";

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  }
})

</script>
<style scoped>
.ofd-view-container {
  width: 100%;
  height: 80vh;
}
</style>

2.7 dplayer 预览

VideoPlay.vue 官方样例:https://github.com/DIYgod/DPlayer

复制代码
<template>
  <div>
    <div id="dplayer" style="height: 80vh"></div>
  </div>
</template>
<script setup>
import {onMounted} from "vue";
import DPlayer from 'dplayer';

const props = defineProps({
  fileUrl: {
    type: String,
    default: undefined
  }
})

onMounted(()=>{
  const dp = new DPlayer({
    container: document.getElementById('dplayer'),
    screenshot: true,
    video: {
      url: props.fileUrl,
    }
  });
})
</script>

<style scoped></style>

三 防止通过预览下载的媒体的方式

复制代码
# 1 前端改进:
地址是传递的方法:每次预览器访问地址会生成1个新token 预览地址

# 2 后端校验
1)后台对资源预览禁用缓存:防止用户直接新页签打开走缓存直接保存文件
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "0");
2)校验是通过安全域名,访问本文件
String referer = request.getHeader("Referer"); 
referer.contains("网站域名")

3)token 合法校验
token 放入 redis,校验存在,访问1次就删除;且校验token用户在登录用户,且token未过期

4)每次访问记录日志,记录访问的ip,用于追溯
相关推荐
初九之潜龙勿用8 天前
C# 操作Word模拟解析HTML标记输出带格式的文本
开发语言·c#·word·office
裤裤兔8 天前
利用VBA批处理word 文档,使用宏对docx文件内容进行批量替换
c#·word·.net··vba·office·宏操作
玩泥巴的16 天前
.NET驾驭Excel之力:工作簿与工作表操作基础
c#·excel·二次开发·office·com互操作
Humbunklung22 天前
Word技巧:制作可勾选的复选框并自定义选中符号
word·office
try_trying_try23 天前
excel下拉选项设置
office
SunkingYang1 个月前
Excel斜线表头怎么做?合并单元格后添加对角线+两侧输入文字,新手也能秒会!
excel·office·单元格·斜线表头·对角线·输入文字·两边
不坑老师1 个月前
怎么在PPT里面插入网页?
microsoft·powerpoint·wps·office
spencer_tseng1 个月前
Custom Animations for PPT (PowerPoint)
powerpoint·ppt·office
Shi_haoliu1 个月前
Vue2 + Office Add-in关于用vue项目于加载项控制excel单元格内容(Demo版)
前端·javascript·vue.js·node.js·html·excel·office