How to implement file preview function in vue

file stream

How to convert the file stream (blob) of various files into data that can be directly previewed online, here is a brief introduction to four different types of file previews. They are pdf, docx, xlsx, jpg/png/jpeg, etc. There is one thing that needs to be paid attention to. The file stream must be guaranteed to be downloaded and parsed before it can support preview. Otherwise, the various plug-ins used below may generate errors. (It is necessary to pay attention to whether the file will be damaged after the file is encrypted and decrypted)

The following is the format of the file stream obtained from the backend:
file stream

docx preview

This is achieved with the help of the plugin docx-preview.

① First install the plugin

npm install docx-preview

② Import the corresponding package

import {
    
     renderAsync } from 'docx-preview';

③Call the function and parse the docx file

renderAsync(res.data, document.getElementById("preload_box"), null, {
    
    
   className: "docx", // 默认和文档样式类的类名/前缀
   inWrapper: true, // 启用围绕文档内容渲染包装器
   ignoreWidth: false, // 禁止页面渲染宽度
   ignoreHeight: false, // 禁止页面渲染高度
   ignoreFonts: false, // 禁止字体渲染
   breakPages: true, // 在分页符上启用分页
   ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
   experimental: false, //启用实验性功能(制表符停止计算)
   trimXmlDeclaration: true, //如果为真,xml声明将在解析之前从xml文档中删除
   debug: false, // 启用额外的日志记录
})

pdf preview

① First install the plugin

npm install pdfjs-dist

② Import the corresponding package

import * as PDFJS from "pdfjs-dist/legacy/build/pdf";  // 引入PDFJS 
import pdfjsWorker from "pdfjs-dist/legacy/build/pdf.worker.entry.js"; // 引入workerSrc的地址

③Call the function to parse the pdf file

const blobPdf = new window.Blob([res.data], {
    
     type: 'application/pdf;chaset-UTF-8' })
const pdfhref = URL.createObjectURL(blobPdf);
PDFJS.getDocument(pdfhref).promise.then(pdfDoc=>{
    
    
   const numPages = pdfDoc.numPages; // pdf的总页数
   // 获取第1页的数据
   pdfDoc.getPage(1).then(page =>{
    
    
      // 设置canvas相关的属性
      const canvas = document.getElementById("pdf_canvas");
      const ctx = canvas.getContext("2d");
      const dpr = window.devicePixelRatio || 1;
      const bsr =
      ctx.webkitBackingStorePixelRatio ||
      ctx.mozBackingStorePixelRatio ||
      ctx.msBackingStorePixelRatio ||
      ctx.oBackingStorePixelRatio ||
      ctx.backingStorePixelRatio ||
      1;
      const ratio = dpr / bsr;
      const viewport = page.getViewport({
    
     scale: 1 });
      canvas.width = viewport.width * ratio;
      canvas.height = viewport.height * ratio;
      canvas.style.width = viewport.width + "px";
      canvas.style.height = viewport.height + "px";
      ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
      const renderContext = {
    
    
      canvasContext: ctx,
      viewport: viewport,
   };
   // 数据渲染到canvas画布上
   page.render(renderContext);
  })
})

Regarding the parsing of pdf, there are several issues to be aware of:

1. In order to correctly parse the pdf, we convert the pdf file stream into a blob address to be read by the parser.
2. Since the plug-in can only query one page of data in the pdf file at a time, we need to add additional logic code for page turning.
3. The element pdf_canvas rendered by pdf must be a canvas tag.

The following is the code for flipping pages:

      // 切换pdf页数
      function changePdfPage (type) {
    
    
        if (type == 'pre') {
    
    
          if (pdfPage.value <= 1) {
    
    
            ElMessage.error('没有上一页了');
            return 
          }
          pdfPage.value -= 1
        } else {
    
    
          if (pdfPage.value >= pdfValue.numPages) {
    
    
            ElMessage.error('没有下一页了');
            return 
          }
          pdfPage.value += 1
        }
        initPdfPage()
      }
      
      // 重新初始化pdf对应页数
      function initPdfPage () {
    
    
        pdfValue.getPage(pdfPage.value).then(page =>{
    
    
          // 设置canvas相关的属性
          const canvas = document.getElementById("pdf_canvas");
          const ctx = canvas.getContext("2d");
          const dpr = window.devicePixelRatio || 1;
          const bsr =
            ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            ctx.backingStorePixelRatio ||
            1;
          const ratio = dpr / bsr;
          const viewport = page.getViewport({
    
     scale: 1 });
          canvas.width = viewport.width * ratio;
          canvas.height = viewport.height * ratio;
          canvas.style.width = viewport.width + "px";
          canvas.style.height = viewport.height + "px";
          ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
          const renderContext = {
    
    
            canvasContext: ctx,
            viewport: viewport,
          };
          // 数据渲染到canvas画布上
          page.render(renderContext);
        })
      }

xlsx preview

① First install the plugin

npm install xlsx

② Import the corresponding package

import * as XLSX from 'xlsx/xlsx.mjs'
<div class="sheet_list">
   <p class="sheet_item" v-for="(item, index) in workbook.SheetNames" @click="getTable(item)">{
   
   {item}}</p>
</div>
<el-table :data="excelData" style="width: 100%">
   <el-table-column
     v-for="(value, key, index) in excelData[0]"
     :key="index"
     :prop="key"
     :label="key"
   ></el-table-column>
</el-table>
 const xlsx_data = await res.data.arrayBuffer()
 let tem_workbook = XLSX.read(xlsx_data, {
    
    type:"array"}); // 解析数据
 workbook.value = tem_workbook
 getTable(tem_workbook.SheetNames[0]); // 读取第一张表数据
 
 // 解析xlsx数据为table
 function getTable(sheetName) {
    
    
    let worksheet = workbook.value.Sheets[sheetName];
    excelData.value = XLSX.utils.sheet_to_json(worksheet);
 }

The xlsx plug-in only helps us parse the data of the excel table, but does not help us typesetting, so usually we need to write our own styles to rearrange the data, and using the table component of element is a good choice.
At the same time, in order to switch multiple tables, we can also traverse the table name array to provide users with the function of switching tables.

image preview

The preview of the picture is relatively simple, without using any plug-ins, and only needs to convert the picture file stream into a blob address that can be consulted.

const blobImage = new window.Blob([res.data], {
    
     type: 'image/' + fileType }) // fileType指图片的类型
const imageHref = URL.createObjectURL(blobImage); // 创造一个地址
preloadImg.value = imageHref // img标签的src属性的值

epilogue

The above are the preview methods of some related files. The plug-ins used are not a single choice, and there are other solutions to achieve our goals. But what needs to be kept in mind is that most plug-ins require us to ensure the integrity of the file before they can be parsed successfully. When completing this function, we need to pay attention to whether the file is lost or damaged when uploading and downloading.

Guess you like

Origin blog.csdn.net/huangzhixin1996/article/details/126196456