vue预览和下载 pdf、ppt、word、excel文档,文件类型为链接或者base64格式或者文件流,

**

方法1:word、xls、ppt、pdf 这些文件, 如果预览的文件是链接可以直接打开,可用微软官方的预览地址

**

 <iframe width="100%" :src="textVisibleURl " id="myFramePPT" style="border: none;background: #f3f5f8"
          title="预览" height="100%"></iframe>
data(){
	return {
		textVisibleURl :''
	}
}

//可用window.open新开页面 或者 iframe 嵌入
//src是你文件的链接,需要可以公网访问,内网不可用,如http://********.docx
 this.textVisibleURl = `https://view.officeapps.live.com/op/embed.aspx?src=${src}`; //去掉头部一些不必要的按钮操作
window.open(this.textVisibleURl)

方法2:word、xls、ppt、pdf 这些文件, 如果预览的文件是类型是文件流或者base64格式

本次我的项目中后端返回的是base64格式,在预览中需要将base64格式转为文件流
在这里插入图片描述

methods:{
getCustomerPoolList() {
      this.$api.getCustomerPoolList({ cityName: this.cityName.toString(), homeId: this.homeInterViewSelected.map(item => 			 item.homeId).toString() }).then(res => {
        res.data.forEach(item => {
          
          //此处两个遍历和预览无关,为业务逻辑,主要区分出文档和图片
          item.mapImageObj = item.fileList.filter(file => {
            return file.fileType == '.png' || file.fileType == '.jpg' || file.fileType == '.jpeg'
          })[0] || {}
          item.annexFileList = item.fileList.filter(file => {
            return file.fileType !== '.png' && file.fileType !== '.jpg' && file.fileType !== '.jpeg'
          }) || {}


			//item.annexFileList为所有文档的数组
          item.annexFileList.forEach((i, index) => {

          	//fileByte为base64格式,如上图,如果你的文件格式直接为文件流,此处 base64Str 到 byteArray 可跳过
            let base64Str = i.fileByte;
            const byteCharacters = atob(base64Str);
            const byteNumbers = new Array(byteCharacters.length);
            for (let i = 0; i < byteCharacters.length; i++) {
              byteNumbers[i] = byteCharacters.charCodeAt(i);
            }
            const byteArray = new Uint8Array(byteNumbers);

		
			//针对不同的文件添加不同的BlobType,此处转为文件流URL,文件为文件流可直接从此处开始
			//fileType 可以从fileName中截取,也可让后端返回
            if (i.fileType == '.pdf') {
              const blob = new Blob([byteArray], { type: 'application/pdf' });
              i.dialogImageUrl = URL.createObjectURL(blob);
             
            } else if (i.fileType == '.docx') {
            
              const blob = new Blob([byteArray], { type: 'application/msword' });
              i.dialogImageUrl = URL.createObjectURL(blob);

            } else if (i.fileType == '.ppt' || i.fileType == '.pptx') {
            
              const blob = new Blob([byteArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });

              i.dialogImageUrl = URL.createObjectURL(blob);
            } else {
            	//此处为excel文件,格式为".xlsx"
              const blob = new Blob([byteArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
              i.dialogImageUrl = URL.createObjectURL(blob);
              return
            }
          })
        })
        this.customerPoolObj = JSON.parse(JSON.stringify(res.data))

      })
    },
}

处理完后的数据,dialogImageUrl 为对象URL,预览全靠这个URL!!!
在这里插入图片描述
开始页面渲染

文件列表展示
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1e0494fa39264352982a21793adb8597.png

预览所需的插件

#docx文档预览组件方法1
npm install @vue-office/docx vue-demi

#docx文档预览组件方法2,本文没有使用此插件预览docx
npm install mammoth

#excel文档预览组件
npm install @vue-office/excel vue-demi

#pdf文档预览组件 ,本文中没有使用此插件预览PDF 
npm install @vue-office/pdf vue-demi

将两个文件复制到public目录下
在这里插入图片描述
在这里插入图片描述

ppt iframe的index.html代码,可适配移动端,pc端可删除适配移动端代码
下面的fileUrl:就是 上面处理完后的 dialogImageUrl

图片中的代码如下

	
   let currentUrl = window.location.href;
    function getUrlParams(url) {
      const paramsRegex = /[?&]+([^=&]+)=([^&]*)/gi;
      const params = {};
      let match;
      while ((match = paramsRegex.exec(url))) {
        params[match[1]] = match[2];
      }
      return params;
    }
    let fileUrl = getUrlParams(currentUrl).fileUrl;
    console.log("fileUrl-->", fileUrl);
	//fileUrl:就是dialogImageUrl 
	// #pptx div的id
 $("#pptx").pptxToHtml({
      pptxFileUrl: fileUrl,
      pptxFileName: "fileName",
      slidesScale: "100%",
      slideMode: false,
      keyBoardShortCut: false,
 });
  // 适配移动端!!
    let timer = setInterval(() => {
      const $slides = $(".slides");
      if ($slides.children().length) {
        const slidesWidth = Math.max(
          ...Array.from($slides.children()).map((s) => s.offsetWidth)
        );
        const $wrapper = $("#pptx");
        const wrapperWidth = window.innerWidth;
        const wrapperHeight = window.innerHeight - 55;
        $wrapper.css({
          transform: `scale(${wrapperWidth / slidesWidth})`,
          "transform-origin": "top left",
          height: wrapperHeight * (1 / (wrapperWidth / slidesWidth)) + "px",
        });
        clearInterval(timer);
      }
    }, 100);

ppt/index.html中获取vue页面传进来的src链接获取到

	  <div class="pdfBox1" v-show="fileObj.show">
      <div class="_head">
        <h5>{{ fileObj.fileName }}</h5>
        <i @click="closeLook" class="el-icon-arrow-left"></i>
      </div>
      <div class="word-wrap">
      	  <!-- 预览pdf -->
        <iframe :src="'./pdf/web/viewer.html?file=' + fileObj.url" height="100%" width="100%" id="iframe" title="预览"
          v-show="fileObj.type === '.pdf'" />
          
        <!-- 预览excel -->
        <vue-office-excel v-if="fileObj.type === '.xlsx'" :src="fileObj.url" @rendered="rendered"
          style="width: 100%; height: 100%" />

        <!-- 无适配图片,预览Docx  -->
        <VueOfficeDocx :src="fileObj.url" v-if="fileObj.type === '.docx'"></VueOfficeDocx>
        <!-- 预览ppt  -->
        <iframe width="100%" :src="pptSrc" id="myFramePPT" v-if="fileObj.type === '.pptx' || fileObj.type === '.ppt'"
          style="border: none;background: #f3f5f8" title="预览" height="100%"></iframe>
    
      </div>
    </div>

文件列表的点击事件调用toFileBlob

<script>

	import VueOfficePdf from "@vue-office/pdf";
	import VueOfficeDocx from '@vue-office/docx'
	import VueOfficeExcel from "@vue-office/excel";
	import "@vue-office/docx/lib/index.css";
	import "@vue-office/excel/lib/index.css";
	export default {
	//val为文件列表的对象,主要参数为
	data(){
		return{
			fileObj: {
				dialogImageUrl:'',
				fileByte:'',
				fileName:'',
				fileType:'',
				url :'',
			},
			pptSrc :''
		}
	}
	
	 toFileBlob(val) {
	            console.log('aaa', val)
	       			
	     		this.fileObj.show = true;
	            this.fileObj.fileName = val.fileName;
	            this.fileObj.type = val.fileType
	            this.fileObj.fileByte = val.fileByte
	            this.fileObj.url = val.dialogImageUrl
	            
				if (val.fileType === '.ppt' || val.fileType === '.pptx') {
					//传入到iframe中
				    this.pptSrc = `/ppt/index.html?fileUrl=${val.dialogImageUrl}`;
				}else if (val.fileType === '.docx') {
	      
	       
	          		//预览word的第二种方法
	          		// let base64Str = val.fileByte;
	                // const byteCharacters = atob(base64Str);
	                // const byteNumbers = new Array(byteCharacters.length);
	                // for (let i = 0; i < byteCharacters.length; i++) {
	                //     byteNumbers[i] = byteCharacters.charCodeAt(i);
	                // }
	                /*  mammoth.convertToHtml({
	                     arrayBuffer: new Uint8Array(byteNumbers)
	                 }).then((resultObject) => {
	                     this.$nextTick(() => {
	                         this.wordText = resultObject.value;
	                     });
	                 }); */
					
					
	            }
	       }     
   </script> 

下载base64类型和文件流文件

  downloadGO(data, reportName) {
      if (!data) {
        return
      }

      let base64Str = data;
      const byteCharacters = atob(base64Str);
      const byteNumbers = new Array(byteCharacters.length);
      for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
      }
      const byteArray = new Uint8Array(byteNumbers);

		//文件流省略上述步骤,直接下述开始,byteArray为文件流
      let url = window.URL.createObjectURL(new Blob([byteArray]))
      let link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.download = reportName //文件名
      document.body.appendChild(link)
      link.click()
    },


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/939916.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Postbot使用教程

1.什么是Postbot&#xff1f; Postbot 是 Postman 中 API 工作流的 AI 助手。您可以让 Postbot 帮助您排查 API 请求问题、编写测试脚本和文档以及理解大型数据集。如果您需要有关使用 Postman 的帮助或不确定下一步该怎么做&#xff0c;也可以向 Postbot 询问。 2.开始使用 …

考试报名管理系统

集中实践报告 ---《项目综合实习1(数据结构)》 题目:考试报名管理系统 系统设计与开发 摘 要 随着教育信息化的不断推进,考试报名管理系统在各类教育机构中的重要性日益凸显。本文旨在设计与实现一个高效、稳定且功能完备的考试报名管理系统,以满足现代教育考试的…

冬日养仓鼠小指南:温暖与陪伴同行

随着冬日的脚步悄然来临&#xff0c;家中可爱的小仓鼠也需要我们给予更多的关怀与呵护。仓鼠虽小&#xff0c;但它们的冬日养护却大有学问&#xff0c;关乎着这些小生命能否健康快乐地度过寒冷季节。 保暖是冬季养仓鼠的首要任务。我们可以为仓鼠的小窝增添一些保暖材料&#…

用C#(.NET8)开发一个NTP(SNTP)服务

完整源码&#xff0c;附工程下载&#xff0c;工程其实也就下面两个代码。 想在不能上网的服务器局域网中部署一个时间服务NTP&#xff0c;当然系统自带该服务&#xff0c;可以开启&#xff0c;本文只是分享一下该协议报文和能跑的源码。网上作为服务的源码不太常见&#xff0c;…

[机器学习]XGBoost(3)——确定树的结构

XGBoost的目标函数详见[机器学习]XGBoost&#xff08;2&#xff09;——目标函数&#xff08;公式详解&#xff09; 确定树的结构 之前在关于目标函数的计算中&#xff0c;均假设树的结构是确定的&#xff0c;但实际上&#xff0c;当划分条件不同时&#xff0c;叶子节点包含的…

51c视觉~合集33

我自己的原文哦~ https://blog.51cto.com/whaosoft/12163849 #Robin3D 3D场景的大语言模型&#xff1a;在鲁棒数据训练下的3DLLM新SOTA! 论文地址&#xff1a;https://arxiv.org/abs/2410.00255代码将开源&#xff1a;https://github.com/WeitaiKang/Robin3D 介绍 多模态…

【游戏中orika完成一个Entity的复制及其Entity异步落地的实现】 1.ctrl+shift+a是飞书下的截图 2.落地实现

一、orika工具使用 1)工具类 package com.xinyue.game.utils;import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.impl.DefaultMapperFactory;/*** author 王广帅* since 2022/2/8 22:37*/ public class XyBeanCopyUtil {private static MapperFactory mappe…

黑马Redis数据结构学习笔记

Redis数据结构 动态字符串 Intset Dict ZipList QuickList SkipList 类似倍增 RedisObject 五种数据类型 String List Set ZSet Hash

GTID详解

概念和组成 1&#xff0c;全局事务表示&#xff1a;global transaction identifiers 2, GTID和事务一一对应&#xff0c;并且全局唯一 3&#xff0c;一个GTID在一个服务器上只执行一次 4&#xff0c;mysql 5.6.5开始支持 组成 GTID server_uuid:transaction_id 如&#xf…

怎么将pdf中的某一个提取出来?介绍几种提取PDF中页面的方法

怎么将pdf中的某一个提取出来&#xff1f;传统上&#xff0c;我们可能通过手动截取屏幕或使用PDF阅读器的复制功能来提取信息&#xff0c;但这种方法往往不够精确&#xff0c;且无法保留原文档的排版和格式。此外&#xff0c;很多时候我们需要提取的内容可能涉及多个页面、多个…

RTU 通信模块赋能智慧路灯远程开关管理,点亮智慧城市节能增效

RTU&#xff08;Remote Terminal Unit&#xff09;远端测控单元在智慧路灯远程开关管理系统中主要负责数据通信和开关控制。能够实现对路灯设备的远程监测和控制&#xff0c;将路灯的状态信息&#xff08;如开关状态、故障信息、亮度参数等&#xff09;上传到管理平台&#xff…

【Canvas与艺术】红色3号桌球

【注】 此图立体感还差点&#xff0c;以后改进吧。 【成图】 120*120的png图标&#xff1a; 大小图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8&q…

从源码分析swift GCD_DispatchGroup

前言&#xff1a; 最近在写需求的时候用到了DispatchGroup&#xff0c;一直没有深入去学习&#xff0c;既然遇到了那么就总结下吧。。。。 基本介绍&#xff1a; 任务组&#xff08;DispatchGroup&#xff09; DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…

线性代数基础与应用:基底 (Basis) 与现金流及单期贷款模型(中英双语)

具体请参考&#xff1a;https://web.stanford.edu/~boyd/vmls/ 下面的例子来源于这本书。 线性代数基础与应用&#xff1a;基底 (Basis) 与现金流及单期贷款模型 在线性代数中&#xff0c;基底&#xff08;Basis&#xff09;是一个重要的概念&#xff0c;广泛应用于信号处理、…

【python】OpenCV—Image Moments

文章目录 1、功能描述2、图像矩3、代码实现4、效果展示5、完整代码6、涉及到的库函数cv2.moments 7、参考 1、功能描述 计算图像的矩&#xff0c;以质心为例 2、图像矩 什么叫图像的矩&#xff0c;在数字图像处理中有什么作用&#xff1f; - 谢博琛的回答 - 知乎 https://ww…

【漏洞复现】CVE-2022-45206 CVE-2023-38905 SQL Injection

漏洞信息 NVD - CVE-2022-45206 Jeecg-boot v3.4.3 was discovered to contain a SQL injection vulnerability via the component /sys/duplicate/check. NVD - CVE-2023-38905 SQL injection vulnerability in Jeecg-boot v.3.5.0 and before allows a local attacker to…

现代风格VUE3易支付用户控制中心

适用系统 彩虹易支付 技术栈 vitevue3elementuiplusphp 亮点 独立前端代码,扩展开发,不改动系统文件,不影响原版升级 支持功能订制 界面预览

开发技术-Java改变图片格式

图片上传页未做控制&#xff0c;导致上传的是GIF格式&#xff0c;导致图片识别失败。需要将GIF格式转为JPEG格式。 代码&#xff0c;是找AI写的&#xff0c;记录一下&#xff1a; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; im…

【计算机视觉基础CV】03-深度学习图像分类实战:鲜花数据集加载与预处理详解

本文将深入介绍鲜花分类数据集的加载与处理方式&#xff0c;同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向&#xff0c;为读者提供从数据组织、预处理、加载到可视化展示的完整过程&#xff0c;并为后续模型训练打下基础。 前言 在计算机视觉的深…

Unity-Editor扩展GUI基本实现一个可拖拉放的格子列表

短短几百行代码,好吧,又是“参考”了国外的月亮 操作,还真地挺自然的。。。。。。国外的实现有点小牛 拖拉,增加+ 一个Element 鼠标左键长按,可以出提示 鼠标右键,清除Element, 有点小bug,不是很自然地完全清除, using System.Collections; using System.Collecti…