天天看點

vue+elementui導入Excel檔案 然後 go-zero進行邏輯處理功能

作者:蜜蜂大蝦

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
    })
}           

上傳的模闆

vue+elementui導入Excel檔案 然後 go-zero進行邏輯處理功能

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()
    }
}           

繼續閱讀