html代码

模板下载 批量导入

js代码

import { uploadConfig } from 'upload' downLoadExlce () { var hrefStr = encodeURI('下载地址的url'); window.location.href = hrefStr; }, // 导入方法 importHandle(item) { const form = new FormData(); const fileObj = item.file; console.log(fileObj); form.append('file', fileObj); uploadConfig(form).then(() => { // 其他逻辑处理, 比如重新获取页面列表接口 this.$notify({ title: '成功', message: '更新成功', type: 'success' }) }) },

请求接口的upload.js

import request from '@/utils/request' /** * 导入上传文件 * @param data */ export function uploadConfig(data) { return request({ url: '/api/upload/fundConfig', method: 'post', headers: { 'Content-Type': 'multipart/form-data' }, data }) }

上传的模板

go-zero 处理逻辑

配置一个config.api文件, 然后执行生成命令

syntax = "v1" info( title: "配置" author: "" ) type ( UploadResp struct { Code string `json:"code"` Message string `json:"message"` } ) @server( prefix: /api/upload ) service admin-api { @doc "配置导入" @handler UploadConfig post /fundConfig returns (UploadResp) }

找到对应的handler 目录下 uploadconfighandler.go 代码

原来的代码 l := internalConfig.NewUploadConfigLogic(r.Context(), svcCtx) 改为 l := internalConfig.NewUploadConfigLogic(r, r.Context(), svcCtx)

找到对应的logic目录下 uploadconfiglogic.go 代码 部分逻辑

import ( "context" "fmt" "net/http" "strconv" "time" "github.com/xuri/excelize/v2" # 这个是关键 "github.com/zeromicro/go-zero/core/logx" ) type UploadConfigLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext r *http.Request } func NewAdFundUploadLogic(r *http.Request, ctx context.Context, svcCtx *svc.ServiceContext) *UploadConfigLogic{ return &UploadConfigLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, r: r, } } func (l *UploadConfigLogic) UploadConfig() (resp *types.UploadResp, err error) { file, handler, err := l.r.FormFile("file") if err != nil { return nil, errorx.NewDefaultError("上传失败:" + err.Error()) } defer file.Close() logx.Infof("upload file: %+v, file size: %d, MIME header: %+v", handler.Filename, handler.Size, handler.Header) //读excel流 xlsx, errs := excelize.OpenReader(file) if errs != nil { return nil, errorx.NewDefaultError("open excel error:[%s]" + err.Error()) } //解析excel的数据 if err2 := l.ReadExcel(xlsx); err2 != nil { return nil, errorx.NewDefaultError("上传失败②:" + err2.Error()) } return &types.UploadResp{ Code: "000000", Message: "添加成功", }, nil } //Employee . type Employee struct { StatDatetime time.Time `db:"stat_datetime"` // 日期。格式:yyyy-MM-dd StatDate string `db:"stat_date"` // 日期。格式:yyyy-MM-dd Appid string `db:"appid"` // 小程序appid GameName string `db:"game_name"` // 游戏名称 AdFund float64 `db:"ad_fund"` // 广告金 } //ReadExcel . func (l *UploadConfigLogic) ReadExcel(xlsx *excelize.File) error { //根据名字获取cells的内容,返回的是一个[][]string rows, _ := xlsx.GetRows(xlsx.GetSheetName(xlsx.GetActiveSheetIndex())) //声明一个数组 var datas []Employee for i, row := range rows { // 去掉第一行是execl表头部分 if i == 0 { continue } var data Employee for k, v := range row { // 第一列是日期 if k == 0 { statDatetime2 := DateStringToDate2(v, "2006-01-02") data.StatDatetime = statDatetime2 data.StatDate = v } // 第二列是Appid if k == 1 { data.Appid = v } // 第三列是游戏名称 if k == 2 { data.GameName = v } // 第四列是广告金 if k == 3 { // string 转float64 n, _ := strconv.ParseFloat(v, 64) data.AdFund = n } } //将数据追加到datas数组中 datas = append(datas, data) } //logx.Info("datas:", datas) //循环遍历datas数组 for k, employee := range datas { key := k + 1 appid := employee.Appid statDate := employee.StatDate gameName := employee.GameName statDatetime2 := employee.StatDatetime adFund := employee.AdFund configOne, errs := l.svcCtx.GameAdFundConfigModel.FindByAppidStatDatetime(appid, statDate) if len(statDate) == 0 { return errorx.NewDefaultError(fmt.Sprintf("第 %s 行,没有填写日期", key)) } if len(appid) == 0 { return errorx.NewDefaultError(fmt.Sprintf("第 %s 行,没有填写appid", key)) } if len(gameName) == 0 { return errorx.NewDefaultError(fmt.Sprintf("第 %s 行,没有填写应用名称", key)) } if adFund < 0 { return errorx.NewDefaultError(fmt.Sprintf("第 %s 行,广告金不能为负数", key)) } # 处理落库逻辑 } return nil } //2022-05-10 字符串 转为 时间类型的 2022-05-10或者20220510 func DateStringToDate2(timeStr string, layout string) time.Time { tt, _ := time.Parse(layout, timeStr) return tt }

excelize 安装与使用

安装命令

go get github.com/xuri/excelize 如果您使用 Go Modules 管理软件包,请使用下面的命令来安装最新版本。 go get github.com/xuri/excelize/v2

创建 Excel 文档

下面是一个创建 Excel 文档的简单例子:

package main import ( "fmt" "github.com/xuri/excelize/v2" ) func main() { f := excelize.NewFile() // 创建一个工作表 index := f.NewSheet("Sheet2") // 设置单元格的值 f.SetCellValue("Sheet2", "A2", "Hello world.") f.SetCellValue("Sheet1", "B2", 100) // 设置工作簿的默认工作表 f.SetActiveSheet(index) // 根据指定路径保存文件 if err := f.SaveAs("Book1.xlsx"); err != nil { fmt.Println(err) } }

读取 Excel 文档

下面是读取 Excel 文档的例子:

package main import ( "fmt" "github.com/xuri/excelize/v2" ) func main() { f, err := excelize.OpenFile("Book1.xlsx") if err != nil { fmt.Println(err) return } defer func() { if err := f.Close(); err != nil { fmt.Println(err) } }() // 获取工作表中指定单元格的值 cell, err := f.GetCellValue("Sheet1", "B2") if err != nil { fmt.Println(err) return } fmt.Println(cell) // 获取 Sheet1 上所有单元格 rows, err := f.GetRows("Sheet1") if err != nil { fmt.Println(err) return } for _, row := range rows { for _, colCell := range row { fmt.Print(colCell, "t") } fmt.Println() } }