• go 操作 Excel


    文档地址:

    https://xuri.me/excelize/zh-hans/

    package main
    
    import (
    	"fmt"
    	"github.com/xuri/excelize/v2"
    )
    
    func main() {
    	readEecel()
    	//writeEecel()
    	//appendEecel()
    }
    
    
    func writeEecel()  {
    	f := excelize.NewFile()
    	// 创建一个工作表
    	index := f.NewSheet("Sheet1")
    	// 设置单元格的值
    	f.SetCellValue("Sheet1", "A2", "Hello world.")
    	f.SetCellValue("Sheet1", "B2", 100)
    	// 设置工作簿的默认工作表
    	f.SetActiveSheet(index)
    	// 根据指定路径保存文件
    	if err := f.SaveAs("Book1.xlsx"); err != nil {
    		fmt.Println(err)
    	}
    }
    func appendEecel()  {
    	fileName := "Book1.xlsx"
    	activeSheet := "Sheet1"
    	f, _:= excelize.OpenFile(fileName)
    	// Get all the rows in the Sheet1.获取所有行的数据 按行获取
    	rows, err := f.GetRows(activeSheet)
    	//获取所有列的内容 按列获取
    	cols, err := f.GetCols(activeSheet)
    	if err != nil {
    		fmt.Println(err)
    		return
    	}
    	fmt.Println("rows_len:", len(rows))
    	fmt.Println("cols_len:", len(cols))
    	//fmt.Println("rows_content:",rows)
    
    	lineHeight, err := f.GetRowHeight(activeSheet,1)
    	fmt.Println("lineHeight:", lineHeight)
    
    	lineLevel, err := f.GetRowOutlineLevel(activeSheet,2)
    	fmt.Println("lineLevel:", lineLevel)
    
    	f.SetCellValue(activeSheet, fmt.Sprintf("A%d",len(rows)+1), fmt.Sprintf("aa%d",len(rows)+1))
    	f.SetCellValue(activeSheet, fmt.Sprintf("B%d",len(rows)+1), fmt.Sprintf("bb%d",len(rows)+1))
    	f.SetCellValue(activeSheet, fmt.Sprintf("C%d",len(rows)+1), fmt.Sprintf("cc%d",len(rows)+1))
    
    	if err := f.SaveAs(fileName); err != nil {
    		fmt.Println(err)
    	}
    }
    
    func readEecel()  {
    	//f, err := excelize.OpenFile("Book1.xlsx")
    	f, err := excelize.OpenFile("信息系统暴露面模板_20211027.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()
    	}
    	fmt.Println("===========================================")
    
    	res:= arrayTwoStringGroupsOf(rows,3)
    	fmt.Println(res)
    
    }
    
    
    func arrayTwoStringGroupsOf(arr [][]string, num int64) [][][]string {
    	max := int64(len(arr))
    	//判断数组大小是否小于等于指定分割大小的值,是则把原数组放入二维数组返回
    	if max <= num {
    		return [][][]string{arr}
    	}
    	//获取应该数组分割为多少份
    	var quantity int64
    	if max%num == 0 {
    		quantity = max / num
    	} else {
    		quantity = (max / num) + 1
    	}
    	//声明分割好的二维数组
    	var segments = make([][][]string, 0)
    	//声明分割数组的截止下标
    	var start, end, i int64
    	for i = 1; i <= quantity; i++ {
    		end = i*num
    		if i != quantity {
    			segments = append(segments, arr[start:end])
    		} else {
    			segments = append(segments, arr[start:])
    		}
    		start = i*num
    	}
    	return segments
    }
    
    func arrayInGroupsOf(arr []int, num int64) [][]int {
    	max := int64(len(arr))
    	//判断数组大小是否小于等于指定分割大小的值,是则把原数组放入二维数组返回
    	if max <= num {
    		return [][]int{arr}
    	}
    	//获取应该数组分割为多少份
    	var quantity int64
    	if max%num == 0 {
    		quantity = max / num
    	} else {
    		quantity = (max / num) + 1
    	}
    	//声明分割好的二维数组
    	var segments = make([][]int, 0)
    	//声明分割数组的截止下标
    	var start, end, i int64
    	for i = 1; i <= quantity; i++ {
    		end = i*num
    		if i != quantity {
    			segments = append(segments, arr[start:end])
    		} else {
    			segments = append(segments, arr[start:])
    		}
    		start = i*num
    	}
    	return segments
    }
    

    应用场景:
    gorm 从 mysql 里分批查出数据,并分批追加写入excel

    // 全量excel分批导出poc
    func (e *ModelExploits) ExportModelExploits(c *gin.Context) {

    msgID := tools.GenerateMsgIDFromContext(c)
    d := new(dto.ModelExploitsSearch)
    //fmt.Println("d222", d)
    db, err := tools.GetOrm(c)
    if err != nil {
    	log.Error(err)
    	return
    }
    
    //查询列表
    err = d.Bind(c)
    if err != nil {
    	e.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
    	return
    }
    
    //数据权限检查
    p := actions.GetPermissionFromContext(c)
    
    serviceStudent := service.ModelExploits{}
    serviceStudent.MsgID = msgID
    serviceStudent.Orm = db
    fileNamePath, err := serviceStudent.ExportModelExploitsPage(d, p)
    if err != nil {
    	e.Error(c, http.StatusUnprocessableEntity, err, "查询失败")
    	return
    }
    
    e.OK(c, gin.H{"filePath": fileNamePath}, "ok")
    

    }

    
    
    unc (e *ModelExploits) ExportModelExploitsPage(c *dto.ModelExploitsSearch, p *actions.DataPermission) (fileNamePath string, err error) {
    	//var err error
    	var data models.ModelExploits
    	msgID := e.MsgID
    
    	dirPath := "static/downloads"                                                          //导出的目录
    	fileName := fmt.Sprintf("%s_%s", time.Now().Format("20060102150405"), "poc_data.xlsx") //文件名称
    	fileNamePath = path.Join(dirPath, fileName)                                            //文件全路径
    	batchSize := 100
    	var lis []models.ModelExploits
    	result := e.Orm.Model(&data).
    		Scopes(
    			cDto.MakeCondition(c.GetNeedSearch()),
    			//cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
    			actions.Permission(data.TableName(), p),
    		).
    		//分批处理
    		FindInBatches(&lis, batchSize, func(tx *gorm.DB, batch int) error {
    			// 批量处理找到的记录
    			total := 0
    			if len(lis) == batchSize {
    				total = batch * batchSize
    			} else {
    				total = (batch-1)*batchSize + len(lis)
    			}
    			fmt.Printf("第 %d 批 , 每批 %d 条 ,已经处理 %d 条\n", batch, batchSize, total) //			batch // Batch 1, 2, 3
    
    			//for _, result := range lis {
    			//	fmt.Println(result.Id)
    			//}
    
    			// 批量处理找到的记录 分批存到excel里
    			err := appendSaveEexcel(dirPath, fileName, &lis)
    			if err != nil {
    				return err
    			}
    			//tx.Save(&lis)
    			//fmt.Println(tx.RowsAffected) // 本次批量操作影响的记录数
    			// 如果返回错误会终止后续批量操作
    			return nil
    		})
    	if result.Error != nil {
    		log.Errorf("msgID[%s] db error:%s", msgID, result.Error)
    		return "", result.Error
    	}
    	//fmt.Printf("total4444---->:%d", len(lis)) //			batch // Batch 1, 2, 3
    
    	//fmt.Println(result.Error) // returned error
    	//fmt.Println(result.RowsAffected) // 整个批量操作影响的记录数
    	return fileNamePath, nil
    }
    
    //save excel 追加写入
    func appendSaveEexcel(dirPath, fileName string, lists *[]models.ModelExploits) error {
    	_ = tools.PathDirCreate(dirPath) //不存在创建目录
    	activeSheetName := "Sheet1"
    	fileNamePath := path.Join(dirPath, fileName)
    	exists, err := tools.PathFileExists(fileNamePath) //判断文件是否存在创建目录
    	rowNum := 0
    	lastLineNum := 0
    	var f *excelize.File
    	// 创建excel
    	if !exists || err != nil {
    		f = excelize.NewFile()
    		// Create a new sheet.
    		index := f.NewSheet(activeSheetName)
    
    		// Set active sheet of the workbook.
    		f.SetActiveSheet(index)
    		// Set tabletitle value of a cell.
    		tableInfo := map[string]string{
    			"A1": "Id",
    			"B1": "Filename",
    			"C1": "Product",
    			"D1": "Fofaquery",
    		}
    		for k, v := range tableInfo {
    			f.SetCellValue(activeSheetName, k, v)
    		}
    	} else { // 追加写入excel
    		f, _ = excelize.OpenFile(fileNamePath)
    		rows, _ := f.GetRows(activeSheetName)
    		lastLineNum = len(rows) //找到最后一行
    	}
    	// Set table content value of a cell.
    	for index, list := range *lists {
    		if !exists || err != nil {
    			//如果不存在从第2行写入
    			rowNum = index + 2
    		} else {
    			//否则从文件内容尾行写入
    			rowNum = lastLineNum + index + 1
    		}
    		f.SetCellValue(activeSheetName, fmt.Sprintf("A%d", rowNum), list.Id)
    		f.SetCellValue(activeSheetName, fmt.Sprintf("B%d", rowNum), list.Filename)
    		f.SetCellValue(activeSheetName, fmt.Sprintf("C%d", rowNum), list.Product)
    		f.SetCellValue(activeSheetName, fmt.Sprintf("D%d", rowNum), list.Fofaquery)
    	}
    	// Save spreadsheet by the given path.  static/downloads/Book1.xlsx
    	if err := f.SaveAs(fileNamePath); err != nil {
    		fmt.Println(err)
    		return errors.New(fmt.Sprintf("save file failed, path:(%s)", fileNamePath))
    	}
    	return nil
    }
    
    
  • 相关阅读:
    全球2/3的DNS瘫痪 顶级域名根服务器故障
    PHP多种形式发送邮件
    IOS开发的基础知识
    Java数字图像处理基础
    将HTML5 Canvas的内容保存为图片
    C# SortedList类概念和示例
    实例对比剖析c#引用参数的用法
    如何理解css中的float
    创建Google网站地图Sitemap.xml
    c#生成静态html文件,封装类
  • 原文地址:https://www.cnblogs.com/haima/p/15913110.html
Copyright © 2020-2023  润新知