vue项目,使用js+Minio实现文件的上传和下载

1 什么是MinIO

MinlO是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据。例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。MinlO是一个非常轻量的服务 可以很简单的和其他应用的结合,类似NodeJS, Redis或者MySQL。

2 使用MinIO实现上传和下载

2.1 安装相关依赖

npm install minio --save

npm install stream --save

2.2 连接minIO服务

参考文档

let Minio = require('minio')
let stream = require('stream')
//连接minio文件服务器
var minioClient = new Minio.Client({
    endPoint: '', //对象存储服务的URL
    port: 9000, //端口号
    useSSL: false, //true代表使用HTTPS
    accessKey: '', //账户id
    secretKey: '', //密码
});

3 示例代码

主要实现功能

  • 用户选择文件夹,将文件夹下文件进行上传
  • 用户可以通过浏览器下载指定文件
<template>
  <div style="margin:5px 5px">
    <el-button @click="getFileName" type="primary">选择文件</el-button>
    <input type="file" webkitdirectory multiple="multiple" id="minIoFile" ref="minIoFile" v-show="false" @change="getFile">
    <el-button v-if="fileList.length>0" type="primary" @click="upload">上传</el-button>
    <el-button type="primary" @click="download">下载</el-button>
  </div>
</template>
<script>
  let Minio = require('minio')
  let stream = require('stream')
  //连接minio文件服务器
  var minioClient = new Minio.Client({
    endPoint: '', //对象存储服务的URL
    port: 9000, //端口号
    useSSL: false, //true代表使用HTTPS
    accessKey: '', //账户id
    secretKey: '', //密码
  });
  export default {
    name: 'MesAdivce',
    data: () => ({
      fileList: [],
    }),
    methods: {
      download(filename, names) {
        minioClient.bucketExists('ecgdata', async function(err) {
          if (err) {
            if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
            return console.log(err)
          }
          //存在
          const file = await new Promise((resolve, reject)=>{
              minioClient.getObject('ecgdata', '4A3D8BF371C044FDB3CED70010801EF5/1.3.12.2.1107.5.6.1.2387.30200122071903025612700000098.DCM', function (err, dataStream) {
                let size = 0;
                let file = [];
                dataStream.on('data', function (chunk) {
                  size += chunk.length
                  console.log(chunk);
                  let aaa = Array.from(chunk)
                  file = file.concat(aaa);
                })
                dataStream.on('end', function () {
                  resolve(file)
                })
                dataStream.on('error', function (err) {
                  resolve(false)
                })
              })
          })
          // 进行下载
          const blob = new Blob([file])
          const blobUrl = URL.createObjectURL(blob)
          const a = document.createElement('a')
          a.setAttribute('href', blobUrl)
          a.setAttribute('download', '1.3.12.2.1107.5.6.1.2387.30200122071903025612700000098.DCM')
          a.click()
        })
      },
      upload() {
        this.fileList.map((item, index) => {
          this.uploadMinIo(item, index);
        })
      },
      getFileName() {
        let inputDOM = this.$refs.minIoFile;
        inputDOM.click();
      },
      getFile(event) {
        let files = document.getElementById('minIoFile').files;
        let arr = [];
        let fileSwitch = true;
        if (files.length > 0) {
          for (let i = 0; i < files.length; i++) {
            if ((files[i].size / 1024 / 1024).toFixed(5) > 64) {
              this.$message({
                message: `${item.name}超过文件的最大长度`,
                type: 'warning'
              });
              fileSwitch = false;
            }
          }
          if (fileSwitch) {
            for (let i = 0; i < files.length; i++) {
              if ((files[i].type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') ||
                (files[i].type == 'application/vnd.ms-excel') ||
                (files[i].type == 'text/plain') ||
                (files[i].type == 'image/png') ||
                (files[i].type == 'image/gif') ||
                (files[i].type == 'image/jpg') ||
                (files[i].type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') ||
                (files[i].type == 'application/vnd.openxmlformats-officedocument.presentationml.presentation')
              ) {
                this.fileList.push(files[i])
              } else {
                console.log("类型不对");
              }
            }
          }
        }
      },
      //上传文件
      uploadMinIo(fileObj, index) {
        this.fileList = this.fileList.filter((self, el) => {
          return self != fileObj
        })
        let vm = this
        // const files = fileObj;
        if (fileObj) {
          let file = fileObj
          //获取文件类型及大小
          const fileName = file.webkitRelativePath
          const mineType = file.type
          const fileSize = file.size
          //参数
          let metadata = {
            "content-type": mineType,
            "content-length": fileSize
          }
          //判断储存桶是否存在
          minioClient.bucketExists('ecgdata', function(err) {
            if (err) {
              if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
              return console.log(err)
            }
            //准备上传
            let reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onloadend = function(e) { //读取完成触发,无论成功或失败
              const dataurl = e.target.result
              //base64转blob
              const blob = vm.toBlob(dataurl)
              //blob转arrayBuffer
              let reader2 = new FileReader()
              reader2.readAsArrayBuffer(blob)

              reader2.onload = function(ex) {
                //定义流
                let bufferStream = new stream.PassThrough();
                //将buffer写入
                bufferStream.end(new Buffer(ex.target.result));
                //上传
                minioClient.putObject('ecgdata', fileName, bufferStream, fileSize, metadata, function(err,
                  etag) {
                  console.log(etag);
                })
              }
            }
          })
        }
      },
      //base64转blob
      toBlob(base64Data) {
        let byteString = base64Data
        if (base64Data.split(',')[0].indexOf('base64') >= 0) {
          byteString = atob(base64Data.split(',')[1]) // base64 解码
        } else {
          byteString = unescape(base64Data.split(',')[1])
        }
        // 获取文件类型
        let mimeString = base64Data.split(';')[0].split(":")[1] // mime类型

        // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
        // let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
        // let uintArr = new Uint8Array(arrayBuffer) // 创建视图

        let uintArr = new Uint8Array(byteString.length) // 创建视图

        for (let i = 0; i < byteString.length; i++) {
          uintArr[i] = byteString.charCodeAt(i)
        }
        // 生成blob
        const blob = new Blob([uintArr], {
          type: mimeString
        })
        // 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
        return blob
      },
    },
  }
</script>

要在Vue.js使用ElementUI实现文件上传功能,可以按照以下步骤进行操作: 1. 安装ElementUI和axios: ``` npm install element-ui axios ``` 2. 在Vue项目中引入ElementUI和axios: ```javascript import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import axios from 'axios' Vue.use(ElementUI) Vue.prototype.$axios = axios ``` 3. 在组件中添加文件上传组件: ```html <template> <div> <el-upload class="upload-demo" action="/upload" :on-success="handleSuccess" :before-upload="beforeUpload" :file-list="fileList" :auto-upload="false"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> </div> </template> ``` 在`el-upload`组件中,我们指定了上传文件的地址和一些属性,例如`before-upload`和`on-success`。在`before-upload`中,我们可以对上传文件进行一些校验,例如文件类型和大小;在`on-success`中,我们可以处理上传成功后的回调。 4. 在组件的`data`选项中添加文件列表: ```javascript export default { data() { return { fileList: [] } }, methods: { handleSuccess(response, file, fileList) { // 处理上传成功后的回调 }, beforeUpload(file) { // 对上传文件进行校验 } } } ``` 5. 在`beforeUpload`方法中,我们可以通过`return false`来阻止上传,或者通过`return true`来允许上传。在这个方法中,我们还可以使用ElementUI的`Message`组件来提示用户上传文件的限制条件: ```javascript beforeUpload(file) { const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' const isLt2M = file.size / 1024 / 1024 < 2 if (!isJPG) { this.$message.error('上传图片只能是 JPG/PNG 格式!') } if (!isLt2M) { this.$message.error('上传图片大小不能超过 2MB!') } return isJPG && isLt2M } ``` 这样,我们就可以在Vue.js使用ElementUI实现文件上传功能了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

it_czh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值