• Vue3 实现文件预览 Word Excel pdf 图片 视频等格式 大全!!!!


    先上效果图

     

     插件安装

    先说 word 文件是docx-preview插件

              excel文件是用 xlsx 插件    

    介绍后端返回的数据

    因为在拦截器处 做了对数据的处理 最后你调接口拿到的数据是 一个对象 里面包含:

    url : blob对象转换的用于访问Blob数据的临时链接。这个链接可以被用于在网页中展示二进制数据,比如显示图像或者播放音视频文件

    blobs:  返回的Blob对象,代表了从网络请求中获取到的二进制数据

    这上下俩部分很重要!!!!!!!!

    如果返回的普通格式的话就大家直接转化

    1. const blob = new Blob([res], { type: 'application/pdf' })  //你需要的类型 转化为blob对象

    2. const url = window.URL.createObjectURL(blob)         //将对象转化为链接


    也就是你后面掉接口返回的数据  

    给大家打印一下 我当时在网上搜索这类资料的时候 就是在这一部分弄糊涂了 对数据格式不了解

     

     然后就到正式书写了

    下载引入插件 (我这是v3 引入 vue2版本 csdn官网上搜vue预览文件 一大堆 大家自己搜一下)

    1. //word文档注释
    2. import { renderAsync } from 'docx-preview';
    3. //excel注释
    4. import * as XLSX from "xlsx";

    Word预览   

    不清楚result 返回内容的往上滑 这里传递的是blob对象!!

    1. <!-- 若是word文档格式数据号展示 我这里是加自己定义的类型判断了 fileType 大家可删除掉 -->
    2. <div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div>
    3. //js代码处
    4. const previewContainer = document.getElementById('fileShow');
    5. renderAsync(result.blob, previewContainer) //渲染

    Excel预览

    不清楚result 返回内容的往上滑 这里传递的是blob对象!!    中间内容是在拿到数据渲染的时候插件数据处理 最后将处理的数据当参数传递到处理样式的方法中

    1. <!-- 若是excel格式数据展示 -->
    2. <div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'">
    3. <div class="tab">
    4. <el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
    5. <el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button>
    6. </el-radio-group>
    7. </div>
    8. <div
    9. style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
    10. <div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div>
    11. </div>
    12. </div>
    13. <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
    14. <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
    15. </div>
    16. //js代码处
    17. //表格预览所需数据 定义
    18. const data = reactive({
    19. excel: {
    20. // 数据
    21. workbook: {},
    22. // 表名称集合
    23. sheetNames: [],
    24. // 激活项
    25. sheetNameActive: "",
    26. // 当前激活表格
    27. SheetActiveTable: ""
    28. }
    29. })
    30. const { excel } = toRefs(data);
    31. // 视频预览所需数据
    32. const emptyTips = ref('暂无内容');
    33. //格式为excel时 方法中书写的内容
    34. const reader = new FileReader(); //创建了一个FileReader对象,这个对象用于异步读取文件内容
    35. //通过readAsArrayBuffer将blob转换为ArrayBuffer对象
    36. reader.readAsArrayBuffer(result.blob) // 这里的res.data是blob文件流
    37. reader.onload = (event) => {
    38. // 读取ArrayBuffer数据变成Uint8Array
    39. var data = new Uint8Array(event.target.result);
    40. // 这里的data里面的类型和后面的type类型要对应
    41. var workbook = XLSX.read(data, { type: "array" });
    42. const sheetNames = workbook.SheetNames // 工作表名称集合
    43. excel.value.workbook = workbook
    44. excel.value.sheetNames = sheetNames
    45. excel.value.sheetNameActive = sheetNames[0]
    46. //方法
    47. getSheetNameTable(sheetNames[0])
    48. };
    49. //定义的方法
    50. const getSheetNameTable = (sheetName) => {
    51. try {
    52. // 获取当前工作表的数据
    53. const worksheet = excel.value.workbook.Sheets[sheetName]
    54. // 转换为数据 1.json数据有些问题,2.如果是html那么样式需修改
    55. let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' })
    56. htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, ')
    57. // 第一行进行改颜色
    58. htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '
    59. )
    60. excel.value.SheetActiveTable = htmlData
    61. } catch (e) {
    62. // 如果工作表没有数据则到这里来处理
    63. excel.value.SheetActiveTable = '

      ' + emptyTips.value + '

      '
    64. }
    65. }
    66. pdf 预览  

      这个需要用到iframe标签  他的blob对象的type需要是"type": "application/pdf"  大家可以看一下自己的blob对象 如果是后端返回的直接是blob格式 但是type不对 那等下我下面代码有转化  如果返回的普通数据 大家自己根据上面的格式自己转化blob对象的时候自己设置一下type 

      1. <!-- 若是pdf数据展示 -->
      2. <iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe>
      3. //js代码处
      4. //格式为pdf时
      5. const reader = new FileReader();
      6. reader.readAsArrayBuffer(result.blob);
      7. reader.onload = function () {
      8. fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" }))
      9. }

      最后是jpg png ,mp4格式预览

      1. //这里就用到blob对象转化的链接了 注意区分!!
      2. if (type == 'jpg' || type == 'png' || type == 'mp4') {
      3. fileAddress.value = result.url
      4. }
      5. //图片类型展示
      6. <img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'">
      7. //视频类型展示
      8. <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
      9. <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
      10. </div>

      下载文件 !!

      1. <el-button @click="DownloadFn()"> 下载</el-button>
      2. // 文件下载
      3. const DownloadFn = () => {
      4. let a = document.createElement('a')
      5. // 下载链接
      6. a.href = blobUploadValue.value //这个就是那个blob链接!!
      7. // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
      8. //这里是你上传的文件名 加上他的类型 jpg,png,docx.....
      9. a.download = fileNameValue.value + '.' + fileType.value
      10. document.body.appendChild(a)
      11. // 点击a标签,进行下载
      12. a.click()
      13. // 移除元素
      14. document.body.removeChild(a)
      15. }

      最后是完整代码 

      1. <el-dialog v-model="dialogTabsVisible" title="附件展示" class="file-show-box" @close="closeDialog()">
      2. <div class="file-body">
      3. <!-- 左侧附件列表 -->
      4. <div class="file-left" >
      5. <div class="list" :class="{'list-active' : listAct == index}" v-for="(item, index) in fileList" :key="index" @click="handleClick(item,index)">{{ item.name }}</div>
      6. </div>
      7. <div class="file-right">
      8. <div class="downFile" v-if="fileType != 'pdf'">
      9. <el-button @click="DownloadFn()"> 下载</el-button>
      10. </div>
      11. <!-- 若是图片数据展示 -->
      12. <img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'">
      13. <!-- 若是txt格式数据展示 -->
      14. <iframe :src="fileAddress" frameborder="0" v-else-if="fileType == 'txt'" style="width: 90%; height: 100%;"></iframe>
      15. <!-- 若是pdf数据展示 -->
      16. <iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe>
      17. <!-- 若是word文档格式数据号展示 -->
      18. <div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div>
      19. <!-- 若是excel格式数据展示 -->
      20. <div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'">
      21. <div class="tab">
      22. <el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
      23. <el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button>
      24. </el-radio-group>
      25. </div>
      26. <div
      27. style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
      28. <div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div>
      29. </div>
      30. </div>
      31. <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
      32. <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
      33. </div>
      34. <div v-else>
      35. 该文件暂不支持预览,请下载查看
      36. </div>
      37. </div>
      38. </div>
      39. </el-dialog>
      40. //js部分
      41. //表格预览所需数据
      42. const data = reactive({
      43. excel: {
      44. // 数据
      45. workbook: {},
      46. // 表名称集合
      47. sheetNames: [],
      48. // 激活项
      49. sheetNameActive: "",
      50. // 当前激活表格
      51. SheetActiveTable: ""
      52. }
      53. })
      54. const { excel } = toRefs(data);
      55. // 视频预览所需数据
      56. const emptyTips = ref('暂无内容');
      57. // 下载文件
      58. // 文件地址
      59. const fileAddress = ref('')
      60. // 下载流数据
      61. const blobUploadValue = ref('')
      62. //我这里的参数type是其他地方传递过来的 注意甄别
      63. const downloadFn = (id, type) => {
      64. let params = { fileId: id }
      65. download(params).then(result => {
      66. console.log(result.url, 'resolve');
      67. console.log(result.blob, 'blob');
      68. blobUploadValue.value = result.url
      69. if (type == 'jpg' || type == 'png' || type == 'mp4') {
      70. //格式为图片 视频时
      71. fileAddress.value = result.url
      72. } else if (type == 'docx') {
      73. //格式为word时
      74. const previewContainer = document.getElementById('fileShow');
      75. renderAsync(result.blob, previewContainer) //渲染
      76. } else if (type == 'xlsx') {
      77. //格式为excel时
      78. const reader = new FileReader();
      79. //通过readAsArrayBuffer将blob转换为ArrayBuffer对象
      80. reader.readAsArrayBuffer(result.blob) // 这里的res.data是blob文件流
      81. reader.onload = (event) => {
      82. // 读取ArrayBuffer数据变成Uint8Array
      83. var data = new Uint8Array(event.target.result);
      84. // 这里的data里面的类型和后面的type类型要对应
      85. var workbook = XLSX.read(data, { type: "array" });
      86. const sheetNames = workbook.SheetNames // 工作表名称集合
      87. excel.value.workbook = workbook
      88. excel.value.sheetNames = sheetNames
      89. excel.value.sheetNameActive = sheetNames[0]
      90. getSheetNameTable(sheetNames[0])
      91. };
      92. } else if (type == 'pdf') {
      93. //格式为pdf时
      94. const reader = new FileReader();
      95. reader.readAsArrayBuffer(result.blob);
      96. reader.onload = function () {
      97. fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" }))
      98. }
      99. }
      100. })
      101. }
      102. // 文件下载
      103. const DownloadFn = () => {
      104. let a = document.createElement('a')
      105. // 下载链接
      106. a.href = blobUploadValue.value
      107. // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
      108. a.download = fileNameValue.value + '.' + fileType.value
      109. document.body.appendChild(a)
      110. // 点击a标签,进行下载
      111. a.click()
      112. // 移除元素
      113. document.body.removeChild(a)
      114. }
      115. const getSheetNameTable = (sheetName) => {
      116. try {
      117. // 获取当前工作表的数据
      118. const worksheet = excel.value.workbook.Sheets[sheetName]
      119. // 转换为数据 1.json数据有些问题,2.如果是html那么样式需修改
      120. let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' })
      121. htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '
      )
    67. // 第一行进行改颜色
    68. htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '
    69. )
    70. excel.value.SheetActiveTable = htmlData
    71. } catch (e) {
    72. // 如果工作表没有数据则到这里来处理
    73. excel.value.SheetActiveTable = '

      ' + emptyTips.value + '

      '
    74. }
    75. }
    76.  这里是后端返回回来一个附件名称列表 我渲染到左侧的附件列表中 然后通过选中不同的附件 右侧展示不同的文件预览 他的文件类型我也是从这里得到的 然后我通过点击不同的附件列表 执行上面的预览方法 获取到不同的blob数据 然后进行展示 

      我只能给大家说一下我的逻辑 毕竟每个人代码不一样 不一定能直接复制  还是希望能帮到大家

      最后贴上效果图

       

    77. 相关阅读:
      java11中String类,StringBuffer类和StringBuilder类区别
      探秘TikTok社群:短视频中的共同体验
      Mybatis-Plus官方分库分表神器,一个依赖轻松搞定!
      java split字符串作业
      Zigbee安全概述
      Webinspect
      TFT-eSPI 库在 ESP32 上的配置和使用(ESP32 for Arduino)
      WPF中 ContextMenu 寻找父物体的一种方案
      学习spring源码的意义是什么呢?有什么高效的源码学习方式吗?
      独立站运营的核心——推广分享
    78. 原文地址:https://blog.csdn.net/m0_65607651/article/details/133887921