func CopyFileDataSource(c *m.ReqContext, cmd m.FileDataSourceCommand) Response {
for _, v := range c.Req.MultipartForm.File {
for _, j := range v {
if strings.HasSuffix(j.Filename, ".csv") {
rfile, err := j.Open()
if err != nil {
fmt.Println(err)
return Error(500, "Failed to open file", err)
}
r := csv.NewReader(rfile)
strs, err := r.ReadAll()
if err != nil {
fmt.Println(err)
return Error(500, "Failed to open file", err)
}
if len(strs) > 0 {
var retSlice []string = make([]string, 0)
//get csv title
length := len(strs[0]);
var title []string = make([]string, length)
for i, str := range strs[0] {
title[i] = str
}
for i, str := range strs {
//str 是一行,除了第一行之外,创建map转换为json,一行的json数据,i 表示第几行
if (i != 0) {
var m = make(map[string]string)
//j表示第几列
for j, tmp := range str {
//tmp 是一行的每一列
m[title[j]] = tmp
}
json, _ := json.Marshal(m)
retSlice = append(retSlice, string(json))
}
}
if WriteFile(cmd, retSlice) {
return Success("File DataSource Saved Successfully!!")
}
}
} else if strings.HasSuffix(j.Filename, ".xls") || strings.HasSuffix(j.Filename, ".xlsx") {
r, err := j.Open()
if err != nil {
fmt.Println(err)
return Error(500, "Failed to open file", err)
}
xlsx, err := excelize.OpenReader(r)
if err != nil {
fmt.Println(err)
return Error(500, "Failed to open file", err)
}
//获取sheet1第一行当作title
sheetMap := xlsx.GetSheetMap()
rows := xlsx.GetRows(sheetMap[1])
length := len(rows)
title := make([]string, length)
for i, str := range rows[0] {
title[i] = str
}
//生成json数据
var retSlice []string = make([]string, 0)
for i, row := range rows {
if i != 0 {
var m = make(map[string]string)
//j表示第几列
for j, colCell := range row {
m[title[j]] = colCell
}
json, _ := json.Marshal(m)
retSlice = append(retSlice, string(json))
}
}
if WriteFile(cmd, retSlice) {
return Success("File DataSource Saved Successfully!!")
}
} else {
return Error(500, "Only Support Upload Csv And Excel File!", nil)
}
}
}
return Error(500, "File Error!", nil)
}
上面的方法是处理获取的文件数据,并转换为json对象。写入项目指定目录。
Go处理excel文件,需要加载Excelize 包。Go代码需要注重对象的定义,go特性
func WriteFile(cmd m.FileDataSourceCommand, retSlice []string) bool {
_, err := os.Stat("./public/filejson/")
if err == nil {
return true
}
if os.IsNotExist(err) {
err := os.Mkdir("./public/filejson/", os.ModePerm)
if err != nil {
fmt.Println(err)
return false
}
}
dstFile, err := os.Create("./public/filejson/" + cmd.Servername + ".json")
if err != nil {
fmt.Println(err)
return false
}
defer dstFile.Close()
fileJson, _ := json.Marshal(retSlice)
dstFile.WriteString(string(fileJson))
return true
}
上述方法,go写文件,并创建目录判断目录是否存在。json的格式化需要使用json包的marshal方法
datasourceFileRequest(options) {
return this.datasourceRequest({
method: options.method,
url: '/api/datasources/filedatasource',
data: options.data,
retry: 0,
headers: options.headers,
transformRequest: options.transformRequest
});
}
上述方法,组装angular $http请求相关参数,在上传文件过程中,需要设置content-type: mutipart/form_data;
transformRequest也是必须的参数,进行了formdata转换