vue+elementui导入Excel文件(基于vue-element-admin中的uploadExcel组件), 然后 go-zero进行逻辑处理功能

news2025/1/10 10:14:01

#前端代码

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 安装与使用

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146451.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.两数相加(链表)

题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会…

【Linux】动静态库的制作和使用

目录 一、可执行文件的形成 二、静态库 2.1 制作静态库 2.2 使用静态库 三、动态库 3.1 动态库的制作 3.2 动态库链接 2.3 动态库的加载 一、可执行文件的形成 在C语言中&#xff0c;函数库文件分为两种类型&#xff1a; 静态库&#xff08;库程序是直接注入目标程序…

想要做成一件事,就得有方法,怎么做到呢

想要完成一件事&#xff0c;没有详细的计划和方法是做不好的。如果没有计划&#xff0c;没有方案&#xff0c;没有策略&#xff0c;没有规划&#xff0c;没有方法&#xff0c;那就是一只无头苍蝇&#xff0c;到处乱撞&#xff0c;不能达到什么目的。想做成一件事&#xff0c;就…

后端人眼中的Vue(二)

三、Vue基本语法 3.1、展示数据 3.1.1、v-text 3.1.1.1、简介 ​ 和插值表达式&#xff08;{{}}&#xff09;一样&#xff0c;用于获取vue实例中data属性声明的数据。用法是在哪个标签上获取就直接在哪个标签上定义v-text或者是v-html。相当于javascript中的innerText。直接…

笔记:Android 系统架构

Android系统架构 1.应用层&#xff08;System Apps&#xff09; 系统内置应用程序和非系统应用程序&#xff0c;源码目录中的 packages 目录对应系统应用层 2.应用架构层&#xff08;Framework&#xff09; 为开发人员提供应用程序开发所需要的API&#xff0c;向下与c/c程序…

J-Tech Talk|跨模态视频检索进阶,一起探索CLIP模型的新天地!

J-Tech Talk由 Jina AI 社区为大家带来的技术分享围绕 Python 的相关话题工程师们将深入细节地讲解具体的问题分享 Jina AI 在开发过程中所积累的经验CLIP 模型在零样本图像分类、跨模态检索中效果拔群&#xff0c;它的出现同时推动了 NLP 和 CV 的发展&#xff0c;为解决许多实…

【自学C++】C++转义字符

C转义字符 C转义字符教程 在编程中有一些字符是打不出来的&#xff0c;比如换行&#xff0c;提示音&#xff0c;下一个制表位等等&#xff0c;于是程序语言的开发者就设计了转义序列&#xff08;escape sequence&#xff09;这种东西用来表达这些字符。 所谓转义&#xff0c…

jvm学习的核心(二)---运行时数据区概述

文章目录1.方法区&#xff08; Method Area&#xff09;2.堆&#xff08;Heap&#xff09;3.本地方法栈&#xff08;Native Method Stacks&#xff09;4.程序计数器&#xff08;pc Register&#xff09;5.虚拟机栈&#xff08;Virtual Machine Stacks&#xff09;运行时数据区 …

IDEA启动项目通过https进行访问,nginx配置https访问

一、IDEA启动项目通过https进行访问 1、获取证书 证书申请网络有很多方法&#xff0c;这里腾讯云的nginx版证书举列 2、证书转换 springboot是识别p12证书的&#xff0c;所有这里需要吧pem证书进行转换。转换工具OpenSSL-Win64&#xff08;自行百度下载&#xff09;下载完…

nodejs操作MySQL数据库

1、操作数据库的步骤 安装操作 MySQL 数据库的第三方模块&#xff08;mysql&#xff09;通过 mysql 模块连接到 MySQL 数据库通过 mysql 模块执行 SQL 语句2、安装与配置 mysql 模块 2.1、安装 mysql 模块 mysql 模块是托管于 npm 上的第三方模块。它提供了在 Node.js 项目中…

【Centos】服务管理、解/压缩、磁盘、进程管理相关命令

文章目录一、服务管理1 service2 chkconfig设置后台服务器的自启配置3 systemctl设置后台服务器自启配置防火墙关闭4 开关机重启5 搜索查找类6 locate快速定位文件路径二、压缩、解压1 gzip2 zip3 tar三、磁盘查看和分区类1 du2 df3 lsblk4 mount5 fdisk四、进程管理类1 iotop2…

Vue基础入门小demo——图片切换(初阶)

文章目录 &#x1f4cb;前言 &#x1f3af;demo介绍 &#x1f3af;完整代码 &#x1f3af;最终效果 &#x1f3af;案例解析 &#x1f4cb;前言 图片切换是一个很经典的Vue入门学习案例&#xff0c;在你学习完一些基本的v-指令后&#xff0c;你可以尝试去写一个简单的demo去…

吴恩达【神经网络和深度学习】Week3——浅层神经网络

文章目录Shallow Neural Network1、Neural Networks Overview2、Neural Network Representation3、Computing a Neural Networks Output4、Vectorizing Across Multiple Examples5、Explanation for Vectorized Implementation6、Activation Functions7、Why do you need Non-L…

年底固定资产盘点的正确招数

企业年终盘点的必要性 年终盘点的最终目的是摸清资产现状&#xff0c;掌握资产情况&#xff0c;为日常管理和来年采购预算做有力数据支撑&#xff0c;指导我们接下来应该怎么去做&#xff0c;对任何一家企业的管理都有着重要意义。 随着企业规模的扩大&#xff0c;员工和企业设…

SCI论文解读复现【NO.4】FINet:基于合成雾和改进YOLOv5的绝缘子数据集和检测基准(代码已复现)

此前出了目标检测算法改进专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的SCI论文&am…

Redisson获取/释放分布式锁流程中使用的方法以及watchDog机制相关源码分析

Redisson获取/释放分布式锁原理以及watchDog机制相关源码分析使用到的重点类继承结构RedissonLockExpirationEntry获取锁的代码逻辑tryLock()tryLock(long waitTime, long leaseTime, TimeUnit unit)tryAcquire(long waitTime, long leaseTime, TimeUnit unit, long threadId)t…

变量作用域 和 多文件编程

变量作用域 目录&#xff1a;变量作用域概念typedef声明局部变量全局变量静态变量c存储类auto 自动存储类static 静态存储register 注册存储类extern 外部存储类多文件编程多文件编程概念步骤include <> 和 #include ""的区别防止头文件重复包含使用宏定义避免…

编写playbook ansible(5)

目录 题目&#xff1a; 1.按照要求定义以下变量。&#xff08;可以在多个位置下定义实现相应操作即可&#xff09; 2.编写任务模块在node1和node2主机中根据以上变量值创建对应文本文件以及用户名和安装软件包。 题目&#xff1a; 1.按照要求定义以下变量。&#xff08;可以…

2. 向量、向量索引、向量修改、向量运算

课程视频链接&#xff1a;https://www.bilibili.com/video/BV19x411X7C6?p1 本笔记参照该视频&#xff0c;笔记顺序做了些调整【个人感觉逻辑顺畅】&#xff0c;并删掉一些不重要的内容 系列笔记目录【持续更新】&#xff1a;https://blog.csdn.net/weixin_42214698/category_…

RMQ问题的ST算法实现(详细解析+图片演示+ST模板代码)

文章目录RMQ问题问题引入ST算法倍增ST递推公式查询任意区间的最值代码实现RMQ问题 RMQ&#xff08;Range Minimum/Maximum Query&#xff09;问题&#xff0c;又叫做区间最值问题&#xff0c;即对于长度为n的数列A&#xff0c;回答若干询问RMQ(A,i,j)(i,j<n)&#xff0c;返…