系列文章目录
本篇文章主要介绍从前端上传本地文件,并存储到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
}
总结
以上就是对于本地文件上传的介绍,网上查阅了大量资料,总算是解决了问题。查阅过程中看到过有许多文章没有放入代码,只说了用中间件什么的,因此特此记录一下。