vue_pdf,word,excel,pptx等文件预览

项目背景:vue3+elementPlus+vite

1.pdf

1.1 iframe预览

+ '#toolbar=0' 拼接到src后,可隐藏iframe顶部的工具栏

javascript 复制代码
<template>
  <div class="viewPDF.vue">
    <uploadFile @file="getFile" accept=".pdf,.PDF" ></uploadFile>
    <iframe :src="fileUrl+ '#toolbar=0'" frameborder="0"></iframe>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import PDFObject from 'pdfobject'
import uploadFile from '@/components/uploadFile.vue'

const fileUrl = ref('https://soft.xiaoz.org/office/hee%20hee.pdf')
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  fileUrl.value = file
}

</script>

<style scoped lang="less">
.pdfobject-container {
  height: 680px;
}
</style>
1.2 pdfobject 插件
javascript 复制代码
<template>
  <div class="viewPDF.vue">
    <uploadFile @file="getFile" accept=".pdf,.PDF" ></uploadFile>
    <div id="mypdf"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import PDFObject from 'pdfobject'
import uploadFile from '@/components/uploadFile.vue'

const fileUrl = ref('https://soft.xiaoz.org/office/hee%20hee.pdf')
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  fileUrl.value = file
  var options = {
    pdfOpenParams: {
      scrollbars: "0",
      toolbar: "0",
      statusbar: "0",
      zoom: "100",
      view: "100%",
      fallbackLink: true,
    }, //禁用工具栏代码等一些配置
  };
  PDFObject.embed(fileUrl.value, '#mypdf', options)
}

</script>
1.3 vue-office/pdf插件
  • 安装
    npm install @vue-office/pdf vue-demi
  • 使用
javascript 复制代码
<template>
  <div class="viewPDF.vue">
    <uploadFile @file="getFile" accept=".pdf,.PDF" ></uploadFile>
    <vue-office-pdf :src="fileUrl"  style="height: 600px" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import VueOfficePdf from '@vue-office/pdf'
import uploadFile from '@/components/uploadFile.vue'

const fileUrl = ref('https://soft.xiaoz.org/office/hee%20hee.pdf')
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  fileUrl.value = file
}
</script>

2. docx

2.1 vue-office/docx插件
  • 安装
    npm install @vue-office/docx vue-demi
  • 使用
javascript 复制代码
<template>
  <div class="viewPDF.vue">
    <uploadFile @file="getFile" accept=".doc,.docx" ></uploadFile>
   <vue-office-docx :src="docx" @rendered="rendered"/>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
import uploadFile from '@/components/uploadFile.vue'

const docx= ref('https://soft.xiaoz.org/office/hee%20hee.pdf')
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  docx.value = file
}
</script>

上传doc后缀的文件,也能成功预览

3.excel

3.1 vue-office/excel插件

只能预览xlsx文件

  • 安装
    npm install @vue-office/excel vue-demi
  • 使用
javascript 复制代码
<template>
  <div class="viewPDF.vue">
    <uploadFile @file="getFile" accept=".doc,.docx" ></uploadFile>
   <vue-office-excel
    :src="excel"
    style="height: 600px"
    @rendered="renderedHandler"
    @error="errorHandler"
  />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import VueOfficeExcel from '@vue-office/excel'
import '@vue-office/excel/lib/index.css'
import uploadFile from '@/components/uploadFile.vue'

const excel = ref('https://501351981.github.io/vue-office/examples/dist/static/test-files/test.xlsx')
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  excel.value = file
}
function renderedHandler() {
  console.log('渲染完成')
}
function errorHandler() {
  console.log('渲染失败')
}
</script>
3.2 xlsx插件

支持xlsx,xls文件的预览

  • 安装
    npm i xlsx@0.17.0
  • 使用
javascript 复制代码
<template>
      <div v-if="tableData.length>0" class="tab">
        <table class="table">
          <thead>
            <tr>
              <th v-for="header in tableHeaders" :key="header">{{ header }}</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(row, rowIndex) in renderData" :key="rowIndex">
              <td v-for="(cell, cellIndex) in row" :key="cellIndex">{{ cell }}</td>
            </tr>
          </tbody>
        </table>
        <div class="btn">
          <div v-for="(item, index) in sheetName" @click="handleSheet(index)" :class="{isActive:activeIndex==index}">{{ item }}</div>
        </div>
      </div>
  </template>
  
  <script setup lang="ts">
  import { ref } from 'vue'
  import XLSX from 'xlsx'
  
  defineExpose({handleFileUpload})
  const tableData = ref<any[]>([])
  const tableHeaders = ref<any[]>([])
  const renderData = ref()
  const sheetName = ref()
  function handleFileUpload(fileCurrent: any) {
    const file = fileCurrent
    if (file) {
      const reader = new FileReader()
      reader.onload = (e: any) => {
        console.log(e.target.result);
        
        const data = new Uint8Array(e.target.result)
        const workbook = XLSX.read(data, { type: 'array' })
        // 获取第一个工作表
        const sheetNameArr = workbook.SheetNames
        sheetName.value = sheetNameArr
        sheetNameArr.forEach((sheetName) => {
          tableData.value.push({
            sheetName: sheetName,
            sheet: XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { header: 1 })
          })
        })
        console.log(tableData.value)
        renderData.value = tableData.value[0].sheet
      }
  
      reader.readAsArrayBuffer(file)
    }
  }
  const activeIndex = ref(0)
  function handleSheet(index:number){
    activeIndex.value = index
    renderData.value = tableData.value[index].sheet
  }
  </script>
  
  <style scoped lang="less">
  .tab{
    height: calc(100% - 7px);
  }
 .table{
    height: calc(100% - 50px);
    overflow: auto;
    display:inline-block
  }
  table {
    width: 100%;
    border-collapse: collapse;
  }
  
  th,
  td,
  tr {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: left;
    font-size: 14px;
    color:#0a0a0a
  }
  
  th {
    background-color: #f2f2f2;
  }
  .btn {
    text-align: left;
    background-color: #f5f6f7;
    display: flex;
    border: 1px solid #e8eaed;
    & > div {
      line-height: 40px;
      height: 40px;
      padding:4px 10px;
      vertical-align: middle;
      border-right: 1px solid #e8eaed;
      color: #000000a6;
      cursor: pointer;
      font-size: 14px;
    }
    .isActive{
      background-color: #fff;
    }
  }
  </style>

4.pptx

4.1 pptxjs插件
  • 安装
    pptxjs管网 下载插件

  • 将下载的内容(lib)放到public文件夹下

  • index.html中引入相关文件

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vite</title>
    <link rel="stylesheet" href="/lib/css/pptxjs.css" />
    <link rel="stylesheet" href="/lib/css/nv.d3.min.css" />

    <script type="text/javascript" src="/lib/js/jquery-1.11.3.min.js"></script>
    <script type="text/javascript" src="/lib/js/jszip.min.js"></script>
    <script type="text/javascript" src="/lib/js/filereader.js"></script>
    <script type="text/javascript" src="/lib/js/d3.min.js"></script>
    <script type="text/javascript" src="/lib/js/nv.d3.min.js"></script>
    <script type="text/javascript" src="/lib/js/pptxjs.js"></script>
    <script type="text/javascript" src="/lib/js/divs2slides.js"></script>

    <script type="text/javascript" src="/lib/js/jquery.fullscreen-min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
  • vue文件中使用
javascript 复制代码
<template>
  <div class="viewXls.vue">
    <uploadFile accept=".pptx,.PPTX"  @file="getFile"></uploadFile>
    <div ref="pptx" id="pptx"></div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const pptxUrl = ref()
const pptx = ref()
function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  pptxUrl.value = file+
  console.log( pptxUrl.value);
  // @ts-ignore
  $("#pptx").pptxToHtml({ 
      pptxFileUrl:  pptxUrl.value, //pptx文件地址
      slidesScale: "100%", 
  })
}
</script>

5. 文本(csv,json,jsonl,md,txt,py等文本类型的文件)

  • 读取文件内容相关方法:
javascript 复制代码
import jschardet from 'jschardet'
//buffer转文字
export async function readText(buffer:any,fileType:string) {
    return new Promise((resolve, reject) => {
      const viewBuf = new Uint8Array(buffer);
      console.log(viewBuf,'viewBuf');
      let str = "";
      for (var index in viewBuf) {
        str += String.fromCharCode(viewBuf[index]);
        // @ts-ignore
        if (index >= 1000) {
          //考虑到效率,只取前1000个用于判断字符集
          break;
        }
      }
      // 判断编码方式的插件,使用上有问题,先写死了编码方式
    //   var codepage = jschardet.detect(str.substring(0, 1000)).encoding;
      let code = fileType=='text/csv'?'GB2312':'UTF-8'
      const reader = new FileReader();
      reader.onload = loadEvent => resolve(loadEvent.target!.result);
      reader.onerror = e => reject(e);
      reader.readAsText(new Blob([buffer]), code);
    });
  }
//文件转buffer
  export async function readBuffer(file:any) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = loadEvent => resolve(loadEvent.target!.result);
      reader.onerror = e => reject(e);
      reader.readAsArrayBuffer(file);
    });
  }
  • vue文件中使用
javascript 复制代码
<template>
 <pre>
    <span v-html="text" 
    style=" white-space: pre-wrap;
    word-wrap: break-word;">
    </span>
  </pre>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { readBuffer, readText } from "@/utils/renderFile";

const text = ref();
const fileType = ref("");
async function getFile(val: any) {
  let file = URL.createObjectURL(val.raw)
  fileType.value = val.raw.type;
  let blobFile = new Blob([val]);
    const buffer = await readBuffer(blobFile);
    text.value = await readText(buffer, fileType.value);
    console.log(text,'text');
}
</script>
相关推荐
王哲晓12 分钟前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_41115 分钟前
无网络安装ionic和运行
前端·npm
理想不理想v17 分钟前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云27 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:1379712058729 分钟前
web端手机录音
前端
齐 飞35 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
神仙别闹1 小时前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
GIS程序媛—椰子2 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0012 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试