前端基于Supermap二次开发上传文件,并存储到SQL Server数据库(涉及文件格式:blob、buffer、blobUrl、base64)

系列文章目录

    本篇文章主要介绍从前端上传本地文件,并存储到SQL Server数据库中,同时存储到Supermap工作空间中。如果只想了解存储到SQL Server数据库的部分,一下也会介绍,二者会分开陈述。上传本地文件的方式和类型有很多种,将在前言部分进行详细介绍。



前言

   如果有做基于Supermap开发,并且涉及文件上传功能可以参考前端Supermap文件上传,这一部分介绍的是上传小型文件(例如jpg、png、pdf等文件),文件大小是kb级的。本人参考官方给出的示例文档并没有找到上传大型文件的方法。虽然Supermap软件的字段类型中有二进制的数据类型,但是小编尝试了base64及blob数据的上传,仍然没有成功。所以选择使用文本型的数据类型存储base64数据(本地文件转化后的数据格式)。超图官方提供的参考链接文件上传
   第二部分讲述从本地上传大型文件到后台服务器,由后端服务器存储至SQL Server数据库。


一、前端Supermap文件上传

原理:在Supermap工作空间中某一数据集中建立一个文本型数据字段,用于存储base64数据(仅限于kb级小型文件)。前端由<input>标签实现本地文件数据上传,其中upload方法在文件上传后立即执行,传入文件为base64格式。

注:网上有一种方法,也是上传本地文件进行存储。他们的方法是将上传得到的base64格式数据转为blob格式,因为blob格式数据可以存储大型文件,这个方法可以用后台存储本地文件至数据库这一部分描述的原理,但是不可以直接套用代码。还有一点,这个方法无法使文件存入Supermap工作空间。

vue文件代码:

<template>
	<div>
		<input type="file" accept="image/*" ref="file" @change="upload"  multiple/>
	</div>
</template>
<script>
export default {
	data() {
        return {
			Base64Arr:[]
		}
    },
	methods:{
		upload(){
            let dataFiles = this.$refs.file.files;
            for(let i=0;i<dataFiles.length;i++){
                let imgFile = new FileReader();
                imgFile.readAsDataURL(dataFiles[i]);
                imgFile.onload = res => {           
                     this.Base64Arr.push(res.target.result)
                };
            }
            this.Base64Arr = []  //第二次上传时将数组刷新
            // URL.createObjectURL(this.dataURLtoBlob(   ))		blob文件转url链接
    	}
	}
}
</script>

这里我放一个Base64转Blob的代码:

		dataURLtoBlob(dataurl) {//将iconBase64编码转为blob(二进制),dataurl为base64数据格式
            var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        }

二、后台存储本地文件至数据库

1.前端文件上传

小编的开发是基于Vue脚手架,借助element ui组件库进行开发。以下代码为上传本地文件到后端,而后端接收到的数据为file数据,存入数据库的是file文件中的buffer类型数据。在SQL Server中创建对应的字段为varbinary(MAX)类型。

vue文件代码:

<template>
	<div>
		<el-upload
          class="upload-demo"
          ref="upload"
          multiple
          :data = "data"
          action="http://localhost:8082/uploadDocument"
          :before-upload="beforeUpload"
          :auto-upload="false">
          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
        </el-upload>

		<el-button type="primary" @click="submitForm">提交</el-button>
	</div>
</template>
<script>
export default {
	data() {
        return {
			data:{PictureID :''}	//传入后台服务器的数据
		}
    },
	methods:{
		beforeUpload(file){//文件上传之前执行
          this.data.fileID = String(file.uid)   //传入文件自带的ID  
        },
        submitForm() {
        	this.$refs.upload.submit();
        },
	}
}
</script>

数据库建表字段如图所示:
在这里插入图片描述

2.后台建立

由nodejs+express脚手架搭建的后台服务,搭建方法参考:链接一详细链接二简略。创建完后端项目后,写连接SQL Server的接口方法时,需要先引入mssql库,这个在npm官网直接收索就可以查到。文件上传的接收处理用到了multer中间件,这个也需要npm引入,具体可参考:Multer详解(Node.js中间件),以及multer实现文件上传功能全解(form上传、fetch请求上传、多文件上传)。下面所写的代码对应上面创建的数据库。

后端服务器代码如下(示例):

var express = require('express');
var router = express.Router();

const multer = require('multer')
const storage = multer.memoryStorage();
const upload = multer({storage:storage})
const sql = require('mssql')
const config = {
  user:'sa',
  password:'',
  server:'',    //服务地址,例如127.0.0.1或者localhost
  database:'',   //数据库名
}

router.post('/uploadDocument',upload.single('file'),(req,res)=>{

  var fileData = req.file.buffer;
  let picyureID = req.body.PictureID
  sql.connect(config,function(err){
    if(err){
      console.log('数据库连接失败');
    }
    let request = new sql.Request()
    request.input('file',sql.VarBinary,fileData)
    request.query(`insert into [PictureTable] (PictureBuffer,PictureID) values (@file,'${picyureID}')`,function(err,record){
      if(err){
        console.log('数据上传失败');
      }
      res.send('数据上传成功')
    })
  })
 
})

module.exports = router;

三、后端读取的文件显示

代码如下:

<iframe src="blobUrl" align="middle" width="100%" height="100%" frameborder="1"></iframe>

js文件代码如下:

    // 向后台服务器发出请求,根据前端检索得到的PictureID获取数据库中对应的数据
    static getDocumentSQL(PictureID){
        let iServerURL = "http://localhost:8082/getDocument"
        let queryData = {PictureID:PictureID}   //let queryData = {PictureID}
        let blobUrl

        $.ajax({
            type: "GET",
            url:iServerURL,
            data:queryData,
            async: false,//ajax同步执行,默认时为异步执行
            success: (result) => {
                let PictureBuffer = result.recordset[0].PictureBuffer	//buffer类型数据
                const arraybuffer = new Int8Array(PictureBuffer.data);  //将buffer转为Int8Array类型,然后转为blob格式
                const blob = new Blob([arraybuffer], { type : 'application/pdf'});
                blobUrl = URL.createObjectURL(blob);	//blob文件转url链接
            },
            error: function (msg) {
              console.log(msg)
            }
        })
        return blobUrl
    }

总结

以上就是对于本地文件上传的介绍,网上查阅了大量资料,总算是解决了问题。查阅过程中看到过有许多文章没有放入代码,只说了用中间件什么的,因此特此记录一下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值