您现在的位置是:首页 >学无止境 >Go语言gin框架项目:按模板导出excel并在网页端下载,并将此接口完成swagger的配置网站首页学无止境

Go语言gin框架项目:按模板导出excel并在网页端下载,并将此接口完成swagger的配置

Dragon_0010 2024-06-18 06:01:03
简介Go语言gin框架项目:按模板导出excel并在网页端下载,并将此接口完成swagger的配置

1.需求

甲方的需求是以这种格式导出一个开工通知单

前端页面是这个样子:

 前端勾选一部分部室,后端根据勾选的这些部室名称进行查询,将查询到的部室主任名字填充到表格对应的位置中,另外将前端传过来的信息都填充到表格的指定位置

先展示一下最后导出的结果:

2.解决方法思路

1.前端以form-data表单形式传过来数据,后端使用gin框架的PostForm方法接收参数,并将参数填充到指定位置

2.前端传过来一些部室,后端对这些部室进行判断,通过部室名去查找部室主任,并将部室主任填充到对应的位置

3.导出excel所使用的库excelize:

go get github.com/xuri/excelize/v2

3.源码及结果展示

1.项目结构

 

2.在网页端下载excel文件(源码)

package file

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func ExcelDown(ctx *gin.Context, filepath string, filename string) {
	ctx.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
	ctx.Writer.Header().Add("Content-Type", "application/msexcel")
	ctx.File(filepath)
}

3.导出excel文件

1.如何配置swagger还有导出excel的步骤和逻辑都有写的很清楚,具体看代码注释

package controller

import (
	"fmt"
	"ginEssential/common"
	"ginEssential/file"
	"ginEssential/model"
	"ginEssential/response"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	"strings"
	"time"
)

//导出开工通知单excel

//	@Summary		导出开工通知单excel
//	@Description	输入信息进行导出
//	@Tags			开工通知管理
//	@Accept			multipart/form-data
//	@Produce		application/msexcel
//	@Param			informNumber	formData	string	true	"通知单编号"
//	@Param			projectName		formData	string	true	"项目名称"
//	@Param			designPhase		formData	string	true	"设计阶段"
//	@Param			projectNumber	formData	string	true	"工程编码"
//	@Param			startTime		formData	string	true	"开始时间"
//	@Param			completionTime	formData	string	true	"完成时间"
//	@Param			designBasis		formData	string	true	"设计依据"
//	@Param			departments		formData	string	true	"专业部室"
//	@Param			remark			formData	string	true	"备注"
//	@Param			technology		formData	string	true	"技保部"
//	@Router			/informs/excel [post]
func InformExcel(ctx *gin.Context) {

	DB := common.GetDB()

	//创建一个新的工作簿
	f := excelize.NewFile()
	//声明工作表的名称
	sheetName := "开工通知单"
	f.SetSheetName("Sheet1", sheetName)
	//往表里面添加数据
	//获取当前时间,填在表头
	now := time.Now()
	currentDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	nowDate := currentDate.Format("2006-1-2")
	//获取通知单编号
	informNumber := ctx.PostForm("informNumber")
	//获取项目名称
	projectName := ctx.PostForm("projectName")
	//获取设计阶段
	designPhase := ctx.PostForm("designPhase")
	//获取工程编码
	projectNumber := ctx.PostForm("projectNumber")
	//获取开始时间
	startTime := ctx.PostForm("startTime")
	//获取完成时间
	completionTime := ctx.PostForm("completionTime")
	//获取设计依据
	designBasis := ctx.PostForm("designBasis")
	//获取前端传来了哪些专业部室
	departments := ctx.PostForm("departments")
	fmt.Println(departments)
	//判断里面有哪些部室
	var department model.Department
	//判断里面有没有规划室
	if strings.Contains(departments, "规划室") {
		//根据规划室查询室主任
		if err := DB.Where("department_name = ?", "规划室").First(&department).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	planDirector := department.DepartmentDirector

	var department1 model.Department
	if strings.Contains(departments, "电气室") {
		if err := DB.Where("department_name = ?", "电气室").First(&department1).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	electricalDirector := department1.DepartmentDirector

	var department2 model.Department
	if strings.Contains(departments, "输电室") {
		if err := DB.Where("department_name = ?", "输电室").First(&department2).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	transmissionDirector := department2.DepartmentDirector

	var department3 model.Department
	if strings.Contains(departments, "土建室") {
		if err := DB.Where("department_name = ?", "土建室").First(&department3).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	constructDirector := department3.DepartmentDirector

	var department4 model.Department
	if strings.Contains(departments, "配电室") {
		if err := DB.Where("department_name = ?", "配电室").First(&department4).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	distributeDirector := department4.DepartmentDirector

	var department5 model.Department
	if strings.Contains(departments, "技经室") {
		if err := DB.Where("department_name = ?", "技经室").First(&department5).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	technologyDirector := department5.DepartmentDirector

	var department6 model.Department
	if strings.Contains(departments, "评审室") {
		if err := DB.Where("department_name = ?", "评审室").First(&department6).Error; err != nil {
			response.Fail(ctx, "部门不存在!", nil)
			return
		}
	}
	evaluateDirector := department6.DepartmentDirector

	//获取备注
	remark := ctx.PostForm("remark")
	//获取技保部
	technology := ctx.PostForm("technology")

	data := [][]interface{}{
		{"工程项目开工通知单"},
		{"时间:", nowDate, nil, nil, nil, "编号:", informNumber, nil, nil},
		{"工程名称", projectName, nil, nil},
		{"设计阶段", designPhase, nil, nil, nil, "工程编码", projectNumber, nil},
		{"工程计划", "开始时间", startTime, nil, nil, "完成时间", completionTime, nil},
		{"设计依据", designBasis, nil},
		{nil, "规划室", nil, nil, nil, "室主任", planDirector, nil},
		{nil, "电气室", nil, nil, nil, "室主任", electricalDirector, nil},
		{nil, "输电室", nil, nil, nil, "室主任", transmissionDirector, nil},
		{"专业部室", "土建室", nil, nil, nil, "室主任", constructDirector, nil},
		{nil, "配电室", nil, nil, nil, "室主任", distributeDirector, nil},
		{nil, "技经室", nil, nil, nil, "室主任", technologyDirector, nil},
		{nil, "评审室", nil, nil, nil, "室主任", evaluateDirector, nil},
		{"备注", remark, nil},
		{"技保部", technology, nil},
	}
	//遍历这个二维数组
	for i, row := range data {
		//按列赋值时,需要指定起始存储坐标
		startCell, err := excelize.JoinCellName("A", i+1)
		if err != nil {
			fmt.Println(err)
			return
		}
		if err := f.SetSheetRow(sheetName, startCell, &row); err != nil {
			fmt.Println(err)
			return
		}
	}
	//合并单元格
	mergeCellRanges := [][]string{
		{"A1", "I1"},
		{"B2", "E2"},
		{"G2", "I2"},
		{"B3", "I3"},
		{"B4", "E4"},
		{"G4", "I4"},
		{"C5", "E5"},
		{"G5", "I5"},
		{"B6", "I6"},
		{"C7", "E7"},
		{"G7", "I7"},
		{"C8", "E8"},
		{"G8", "I8"},
		{"C9", "E9"},
		{"G9", "I9"},
		{"C10", "E10"},
		{"G10", "I10"},
		{"C11", "E11"},
		{"G11", "I11"},
		{"C12", "E12"},
		{"G12", "I12"},
		{"C13", "E13"},
		{"G13", "I13"},
		{"B14", "I14"},
		{"B15", "I15"},
		{"A7", "A9"},
		{"A11", "A13"},
	}
	for _, ranges := range mergeCellRanges {
		if err := f.MergeCell(sheetName, ranges[0], ranges[1]); err != nil {
			fmt.Println(err)
			return
		}
	}
	//创建格式,居中对齐
	style1, err := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{Horizontal: "center"},
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	//将样式应用到具体的单元格中
	if f.SetCellStyle(sheetName, "A1", "I15", style1); err != nil {
		fmt.Println(err)
		return
	}
	//保存生成的excel
	//用当前时间来给文件命名
	currentTime1 := time.Now().Format("20060102-150405")
	kai := "start"
	filename := kai + currentTime1 + ".xlsx"
	filepath := "Book1.xlsx"
	err5 := f.SaveAs(filepath)
	// 按照给定路径保存excel
	if err5 != nil {
		response.Fail(ctx, "导出失败", nil)
	} else {
		//下载
		file.ExcelDown(ctx, filepath, filename)
	}
}

 2.参数传递以及结果展示:

 

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。