vue 文件本地預(yù)覽 -通過(guò)vue-office (pdf、xlsx、xls、doc、docx、ppt)

首先,按需拉取,依賴和項(xiàng)目對(duì)應(yīng)的版本 ,引入方法,和調(diào)用方法,根據(jù)版本來(lái)

  • npm install @vue-office/docx
  • npm install @vue-office/pdf
  • npm install @vue-office/excel
  • npm install @vue-office/pptx
  • 根據(jù)版本,有的需要 npm install @vue/composition-api
image.png

如果pdf不需要修改樣式,可以使用iframe

<template>
  <div id="docx-demo">
    <div class="file-info">
      <h3>正在預(yù)覽: {{ selectedFile.name }}</h3>
      <p>文件大小: {{ formatFileSize(selectedFile.size) }}</p>
    </div>
    <div class="loading" v-if="loading">
      <div class="spinner"></div>
      <p>加載中,請(qǐng)稍候...</p>
    </div>
    <el-upload
      :limit="1"
      :file-list="fileList"
      :beforeUpload="beforeUpload"
      action=""
    >
      <el-button size="small" type="warning">點(diǎn)擊上傳</el-button>
    </el-upload>

    <vue-office-docx
      v-if="fileType === 'docx' || fileType === 'doc'"
      :src="src"
      @rendered="onRendered"
      @error="onError"
    />
    <vue-office-excel
      :src="excel"
      v-if="fileType === 'xlsx' || fileType === 'xls'"
      :options="options"
      style="height: 500px"
      @rendered="onRendered"
      @error="onError"
    />
    <vue-office-pdf
      v-if="fileType === 'pdf'"
      :src="pdf"
      style="height: 100vh"
      @rendered="onRendered"
      @error="onError"
    />
    <div
      class="custom-ppt-viewer"
      v-if="fileType === 'pptx' || fileType === 'ppt'"
    >
      <vue-office-pptx :src="ppt" @rendered="onRendered" @error="onError" />
    </div>
    <iframe
      :src="previewUrl"
      frameborder="0"
      class="pdf-iframe"
      @load="handleIframeLoad"
      @error="handleIframeError"
    ></iframe>
  </div>
</template>

<script>
import VueOfficeDocx from "@vue-office/docx";
import "@vue-office/docx/lib/index.css";
//引入VueOfficeExcel組件
import VueOfficeExcel from "@vue-office/excel";
//引入相關(guān)樣式
import "@vue-office/excel/lib/index.css";
import VueOfficePdf from "@vue-office/pdf";
import VueOfficePptx from "@vue-office/pptx";

export default {
  components: {
    VueOfficeDocx,
    VueOfficeExcel,
    VueOfficePdf,
    VueOfficePptx,
  },
  data() {
    return {
      ppt: "",
      previewUrl: "",
      acceptTypes: ".docx,.xlsx,.pptx,.pdf",
      loading: false,
      fileType: "",
      selectedFile: { name: "", size: 0 },
      pdf: "",
      excel: "",
      src: "",
      fileList: [],
      options: {
        xls: false, //預(yù)覽xlsx文件設(shè)為false;預(yù)覽xls文件設(shè)為true
        // minColLength: 0, // excel最少渲染多少列,如果想實(shí)現(xiàn)xlsx文件內(nèi)容有幾列,就渲染幾列,可以將此值設(shè)置為0.
        // minRowLength: 0, // excel最少渲染多少行,如果想實(shí)現(xiàn)根據(jù)xlsx實(shí)際函數(shù)渲染,可以將此值設(shè)置為0.
        widthOffset: 10, //如果渲染出來(lái)的結(jié)果感覺(jué)單元格寬度不夠,可以在默認(rèn)渲染的列表寬度上再加 Npx寬
        heightOffset: 10, //在默認(rèn)渲染的列表高度上再加 Npx高
        beforeTransformData: (workbookData) => {
          return workbookData;
        }, //底層通過(guò)exceljs獲取excel文件內(nèi)容,通過(guò)該鉤子函數(shù),可以對(duì)獲取的excel文件內(nèi)容進(jìn)行修改,比如某個(gè)單元格的數(shù)據(jù)顯示不正確,可以在此自行修改每個(gè)單元格的value值。
        transformData: (workbookData) => {
          return workbookData;
        }, //將獲取到的excel數(shù)據(jù)進(jìn)行處理之后且渲染到頁(yè)面之前,可通過(guò)transformData對(duì)即將渲染的數(shù)據(jù)及樣式進(jìn)行修改,此時(shí)每個(gè)單元格的text值就是即將渲染到頁(yè)面上的內(nèi)容
      },
    };
  },
  methods: {
    // 檢查文件大小 (這里限制為10MB)
    // const maxSize = 10 * 1024 * 1024; // 10MB
    // if (file.size > maxSize) {
    //   this.errorMessage = '文件大小不能超過(guò)10MB';
    //   return;
    // }
    // 處理iframe加載完成
    handleIframeLoad() {
      console.log("PDF預(yù)覽加載完成");
    },

    // 處理iframe加載錯(cuò)誤
    handleIframeError() {
      this.errorMessage = "PDF預(yù)覽失敗,請(qǐng)嘗試重新上傳";
    },
    formatFileSize(bytes) {
      if (bytes === 0) return "0 Bytes";
      const k = 1024;
      const sizes = ["Bytes", "KB", "MB", "GB"];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    },
    onRendered() {
      this.loading = false;
      console.log("文檔渲染完成");
    },
    onError(err) {
      this.loading = false;
      this.error = "文檔預(yù)覽失敗: " + err.message;
      console.error("預(yù)覽錯(cuò)誤:", err);
    },
    //在beforeUpload中讀取文件內(nèi)容
    beforeUpload(file) {
      if (!file) return;
      this.selectedFile = file;
      this.error = "";
      this.loading = true;
      // 獲取文件類型
      const fileName = file.name.toLowerCase();
      if (fileName.endsWith(".docx")) {
        this.fileType = "docx";
      } else if (fileName.endsWith(".doc")) {
        this.fileType = "doc";
      } else if (fileName.endsWith(".ppt")) {
        this.fileType = "ppt";
      } else if (fileName.endsWith(".xlsx")) {
        this.fileType = "xlsx";
      } else if (fileName.endsWith(".xls")) {
        this.fileType = "xls";
      } else if (fileName.endsWith(".pptx")) {
        this.fileType = "pptx";
      } else if (fileName.endsWith(".pdf")) {
        this.fileType = "pdf";
      } else if (fileName.endsWith(".txt")) {
        this.fileType = "txt";
      } else {
        this.error = "不支持的文件格式";
        this.loading = false;
        return;
      }
      let reader = new FileReader();
      reader.readAsArrayBuffer(file);
      reader.onload = (loadEvent) => {
        let arrayBuffer = loadEvent.target.result;
        if (this.fileType == "xlsx" || this.fileType == "xls") {
          this.excel = arrayBuffer;
        } else if (this.fileType == "docx" || this.fileType == "doc") {
          this.src = arrayBuffer;
        } else if (this.fileType == "pptx" || this.fileType == "ppt") {
          this.ppt = arrayBuffer;
        }
        if (this.fileType == "pdf" || this.fileType == "txt") {
          this.pdf = arrayBuffer;
          this.previewFile(file);
        }
      };

      return false;
    },
    // 預(yù)覽PDF文件
    previewFile(file) {
      // 模擬上傳進(jìn)度
      this.uploadProgress = 0;
      const interval = setInterval(() => {
        this.uploadProgress += 10;
        if (this.uploadProgress >= 100) {
          clearInterval(interval);
          // 創(chuàng)建文件的臨時(shí)URL用于預(yù)覽
          this.previewUrl = URL.createObjectURL(file);
        }
      }, 200);
    },
  },
};
</script>
<style scoped>
.pdf-iframe {
  width: 100%;
  height: 400px;
}
.custom-ppt-viewer {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  height: 700px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.custom-ppt-viewer .slide-container {
  background-color: #f9f9f9;
  margin-bottom: 20px;
  border-radius: 8px;
  overflow: hidden;
}

</style>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容