html代碼
<el-button v-waves class="filter-item" type="primary" icon="add" @click="downLoadExlce">模闆下載下傳</el-button>
<el-upload class="upload" action :multiple="false" :show-file-list="false" accept=".xls" :drag="false" :http-request="importHandle">
<el-button slot="trigger" type="primary">批量導入</el-button>
</el-upload>
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()
}
}