[Vue3]上传本地docx文件+实时预览文档

依赖: ant-design-vue,@ant-design/icons-vue ,docx-preview

上传组件:ant design vue的upload

预览组件: docx-preview

单文件上传+浏览

思路

上传组件默认会帮用户发送请求,但是我不想用这个功能。。。看API,beforeUpload属性可以传入方法,每次选择文件后都会被调用。如果这个方法return false就会阻止后续的上传(相当于让我们自己去手动上传)

在这个方法里,我想:

  1. 读取刚刚上传的文件

  1. 把文件转化成docx-preview组件能接受的形式

  1. 渲染docx-preview的dom元素

  1. 最后return false,阻止组件的自动发送请求

步骤1可以直接通过beforeUpload方法的传参获取;步骤34照着组件api抄就完事。

难点还是步骤2:获取的是File类型,需要转换为Blob类型。鼓捣了一阵后,我发现一种可以实现的方式是File -> Base64 -> Blob。(参考文档:Base64、Blob、File ,dataUrl 相互转化三种类型的相互转换

示例
<script setup>
import { ref } from 'vue'
import { InboxOutlined } from '@ant-design/icons-vue'
import { renderAsync } from 'docx-preview'

const fileList = ref([])
const fileBlob = ref(null)
const beforeUpload = file => {
  const fileReader = new FileReader()
  fileReader.readAsDataURL(file)
  fileReader.onload =  (e) => {
    const dataURL = e.target.result
    const arr = dataURL.split(',')
    const defaultMimeType = arr[0].match(/:(.*?);/)[1]
    const bStr = atob(arr[1])
    let n = bStr.length
    const u8arr = new Uint8Array(n)
    while (n--) {
      u8arr[n] = bStr.charCodeAt(n)
    }
    const blob = new Blob([u8arr], { type: file.type || defaultMimeType })
    fileBlob.value = blob
    renderAsync(blob, document.getElementById('doc-container'), null, {
      className: 'docx', // 默认和文档样式类的类名/前缀
      inWrapper: true, // 启用围绕文档内容渲染包装器
      ignoreWidth: false, // 禁止页面渲染宽度
      ignoreHeight: false, // 禁止页面渲染高度
      ignoreFonts: false, // 禁止字体渲染
      breakPages: true, // 在分页符上启用分页
      ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
      experimental: false, //启用实验性功能(制表符停止计算)
      trimXmlDeclaration: true, //如果为真,xml声明将在解析之前从xml文档中删除
      debug: false // 启用额外的日志记录
    })
  }
  return false
}
</script>

<template>
  <div>
    <a-upload-dragger
      v-model:fileList="fileList"
      name="file"
      accept=".docx"
      :before-upload="beforeUpload"
      :max-count="1"
    >
      <p class="ant-upload-drag-icon">
        <inbox-outlined></inbox-outlined>
      </p>
      <p class="ant-upload-text">点击或拖拽文件到此处</p>
      <p class="ant-upload-hint">(最大上传文件数:1)</p>
    </a-upload-dragger>

    <div id="doc-container"></div>
  </div>
</template>

多文件上传+浏览

上传组件里的max-count属性改为文件上限,这样这个组件就能接受多个文件同时上传了。

beforeUpload里还是一样转换刚刚上传的文件,然后把Blob保存到某个ref里。再根据自己的需求去决定用哪个blob渲染预览的dom(甚至可以渲染多个dom同时展示多个文件)。

另外,上传组件里的fileList保存的是已上传文件列表,包含每个文件的信息。比如fileList.value[0].name就是第一个文件的名称(不包括后缀)。更多信息可以直接把这个列表打印出来自己看。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

该写代码了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值