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

发布于:2024-12-22 ⋅ 阅读:(16) ⋅ 点赞:(0)

**

方法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()
    },



网站公告

今日签到

点亮在社区的每一天
去签到