Go语言生成excel、将excel保存到本地、将多个excel表格压缩为压缩包、在压缩文件上传OSS删除本地excel文件和压缩包

news2024/9/20 10:38:03

        最近在公司了个需求,主要涉及到文件导出,需要根据特定表格文件生成excel文件导出,同时对导出的excel临时保存本地,生成压缩包,将压缩包上传至OSS(Object Storage Service)后删除本地临时文件。下面的文章中将对以上涉及到的几个点编写代码实现。

Go语言对excel文件的操作

        Go中对excel文件的操作主要依赖于Excelize库,提供了一组函数,可以对XLAM / XLSM / XLSX / XLTM / XLTX文件进行读写。支持读写由Microsoft Excel™2007及以后版本生成的电子表格文档。通过高兼容性支持复杂组件,并提供流API从具有大量数据的工作表中生成或读取数据。该库需要Go 1.16或更高版本。

        首先通过以下命令获取excelize依赖:

ge get github.com/xuri/excelize/v2

        常见的对excel文件的操作包括:生成excel表格、生成sheet页、向对应sheet页中的cell单元格内填写数据(对excel文件操作的基本步骤)。代码如下:

func genExcelFile() (err error) {
    // 创建一个新的Excel文件1
	f1 := excelize.NewFile() 
	// 在Excel中创建一个新的sheet页
	f1.NewSheet("Sheet1")
	// 向工作表中写入数据
	if err = f1.SetCellValue("Sheet1", "A1", "Hello, World!"); err != nil {
		return
	}
    
    // 创建一个新的Excel文件2
	f2 := excelize.NewFile() 
	// 在Excel中创建一个新的sheet页
	f2.NewSheet("Sheet1")
	if err = f2.SetCellValue("Sheet1", "B1", 123); err != nil {
		return
	}
	return
}

        上述代码给出了对excel文件操作的基本思路实现,在公司中不可能让自己单独实现一个excel的SDK对文件进行导出操作。具体学习参考下述链接:一文搞懂Go读写Excel文件_go excel-CSDN博客

将生成的excel文件保存到本地

        我在公司中做的需求需要同时导出多个excel文件,一个excel文件又包含多个sheet页,最终测试环境导出数据量达6W条之多。我需要将导出的多个excel文件生成一个压缩包。可能会问为什么需要将excel文件暂时保存到磁盘中,而不是暂时保存到内存中等所有的excel文件生成后直接在内容中将其生成zip文件。最终数据量非常大,若将其直接保存到内存中等所有excel表格生成后,将其合并生成zip文件是非常不明智的决定,对于内存的压力巨大。正确的做法每生成一个excel文件将其保存到磁盘目录中,等到所有excel文件生成后,遍历并读取所有excel文件,每遍历一个压缩一个,最终生成一个zip文件。并在将zip文件上传至OSS后删除磁盘文件。

        在上面的步骤中我们得到了 file *excelize.File 类型的excel文件,在填充了对应sheet单元格中具体内容后,需要将其保存到磁盘。借助于和File文件绑定的SaveAs()方法可以实现。

        在得知以上方法之后,自己编写了一个简易的文件保存方法:

const(
    celFilePath = "excelFiles"
)
func saveExcelFile(file *excelize.File, sub string) (path string, err error) {
	path = filepath.Join(excelFilePath, fmt.Sprintf("%s%s", sub, "test.xlsx"))
	
	if err = file.SaveAs(path); err != nil {
		return "", err
	}
	return path, nil
}

        将对应的excel文件保存到当前项目下并且创建一个excelFiles文件夹用以保存所有excel文件。上述代码最终报错:

open excelFiles/1test.xlsx: no such file or directory

        显示对应路径不存在。之前并没有创建临时目录,我本以为SavaAs方法在对应目录不存在时会创建对应的目录,和文件,但实验过后发现并非如此。在写入本地对应目录前,需要借助os.MkdirAll()函数判断对应目录是否存在,如果不存在会创建对应的目录,包含子目录。 

        修改后代码如下所示:

func saveExcelFile(file *excelize.File, sub string) (path string, err error) {
	path = filepath.Join(excelFilePath, fmt.Sprintf("%s%s", sub, "test.xlsx"))
	if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
		return "", err
	}
	if err = file.SaveAs(path); err != nil {
		return "", err
	}
	return path, nil
}

        执行创建excel,并将excel写入本地代码后在项目文件夹下创建 excelFiles 文件夹用以存储所有excel文件,效果如下:

使用压缩工具将多个excel文件压缩为压缩包

        最终根据保存的excel文件路径去遍历读取每个excel文件并将其添加到zip压缩文件中。此时需要记住 "archive/zip" 依赖中的 zip.NewWriter(zipFile) 创建zip文件写入器:

    // zip压缩文件存放路径
    zipFilePath = filepath.Join(excelFilePath, excelZipName)
	// 创建ZIP文件
	zipFile, err := os.Create(zipFilePath)
	if err != nil {
		return "", err
	}
	defer zipFile.Close()
	// 创建ZIP写入器
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()

        随后遍历读取所有excel文件,并将其写入到zip压缩文件中。

删除临时文件及目录

        使用  os.RemoveAll(excelFilePath) 可以删除对应目录下的文件及目录。

        此外自己代码编写过程中学习了如何删除对应目录下的所有文件,不删除对应目录:

func deleteFiles(path string) error {
	// 要删除文件的目录
	// 读取目录中的所有文件
	files, err := os.ReadDir(path)
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 遍历所有文件
	for _, file := range files {
		err := os.Remove(filepath.Join(path, file.Name()))
		if err != nil {
			fmt.Println(err)
			return err
		}
	}

	return nil
}

代码及效果展示 

        最终代码展示了如何创建多个excel、将excel写入本地磁盘、遍历读取磁盘excel生成zip文件、将zip文件上传到OSS(伪代码)、删除临时文件:注释defer中的删除临时目录及文件后代码如下:

package main

import (
	"archive/zip"
	"fmt"
	"github.com/xuri/excelize/v2"
	"io"
	"os"
	"path/filepath"
)

const (
	excelFilePath = "excelFiles"
	excelZipName  = "wwtTest.zip"
)

func main() {
	defer func() {
		//os.RemoveAll(excelFilePath)
	}()
	genExcelFile()
}

func genExcelFile() (err error) {
	f1 := excelize.NewFile() // 创建一个新的Excel文件
	// 在Excel中创建一个新的工作表
	f1.NewSheet("Sheet1")
	// 向工作表中写入数据
	if err = f1.SetCellValue("Sheet1", "A1", "Hello, World!"); err != nil {
		fmt.Println(err)
		return
	}
	f2 := excelize.NewFile() // 创建一个新的Excel文件

	// 在Excel中创建一个新的工作表
	f2.NewSheet("Sheet1")
	if err = f2.SetCellValue("Sheet1", "B1", 123); err != nil {
		fmt.Println(err)
		return
	}
	path1, err := saveExcelFile(f1, "1")
	if err != nil {
		fmt.Println(err)
		return
	}
	path2, err := saveExcelFile(f2, "2")
	if err != nil {
		fmt.Println(err)
		return
	}
	// 获取zip文件
	zipFilePath, _ := genZipFiles([]string{path1, path2})
	fmt.Println(zipFilePath)

    // 将zip文件上传至OSS 
    // TODO
	return
}
func saveExcelFile(file *excelize.File, sub string) (path string, err error) {
	path = filepath.Join(excelFilePath, fmt.Sprintf("%s%s", sub, "test.xlsx"))
	if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
		return "", err
	}
	if err = file.SaveAs(path); err != nil {
		return "", err
	}
	return path, nil
}

func genZipFiles(filePaths []string) (zipFilePath string, err error) {
	zipFilePath = filepath.Join(excelFilePath, excelZipName)
	// 创建ZIP文件
	zipFile, err := os.Create(zipFilePath)
	if err != nil {
		return "", err
	}
	defer zipFile.Close()
	// 创建ZIP写入器
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()
	// 遍历文件列表,逐个添加到ZIP文件中
	for _, filePath := range filePaths {
		if err = addFileToZip(zipWriter, filePath); err != nil {
			return "", err
		}
	}
	return zipFilePath, nil
}

// 将文件写入zip压缩器
func addFileToZip(zipWriter *zip.Writer, filePath string) error {
	// 打开要添加的文件
	file, err := os.Open(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	// 获取文件信息
	fileInfo, err := file.Stat()
	if err != nil {
		return err
	}

	// 创建ZIP文件中的文件头
	zipHeader, err := zip.FileInfoHeader(fileInfo)
	if err != nil {
		return err
	}

	// 将文件头写入ZIP文件
	writer, err := zipWriter.CreateHeader(zipHeader)
	if err != nil {
		return err
	}

	// 将文件内容复制到ZIP文件中
	_, err = io.Copy(writer, file)
	if err != nil {
		return err
	}
	return nil
}

        效果如下:

参考链接

一文搞懂Go读写Excel文件_go excel-CSDN博客

 Golang 生成压缩文件教程_golang 压缩文件-CSDN博客

golang 实现多文件压缩下载_golang将多个文件压缩到一起-CSDN博客 

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

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

相关文章

cpu飙升时的排查方式、线上环境常规排查步骤

提示:面试问题:cpu飙升时的排查方式、生产问题排查方式 文章目录 前言一、cpu飙升时的排查步骤1、top2、top -Hp pid3、printf ‘0x%x’ tid4、jstack pid | grep tid 二、总结三、线上环境常规排查步骤1、查看服务器中线程情况2、查看系统异常进程的16进…

JavaEE 从入门到精通(一) ~ Maven

晚上好,愿这深深的夜色给你带来安宁,让温馨的夜晚抚平你一天的疲惫,美好的梦想在这个寂静的夜晚悄悄成长。 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 在软件开发的日常工作中,有效的项目管理是…

OCC 模型编辑

目录 一、简介 二、主要功能 三、常用方法 四、详细子类示例 1、BRepBuilderAPI_Copy 1.1 形状复制 注意事项 1.2 复制和变换 2、BRepBuilderAPI_Transform 3、BRepBuilderAPI_GTransform 3.1 应用广义仿射变换 3.2 平移和旋转变换 3.3 缩放 4、BRepBuilderAPI_Nu…

shell正则表达式和文本处理器

文章目录 一,正则表达式1.基础正则表达式1.1 字符匹配1.2 元字符1.3 字符集1.4 预定义字符集1.5 量词1.6 非打印字符 2.扩展正则表达式2.1分组和引用2.2 选择2.3 量词 二,文件处理器1.grep2.sed3.egredp4.awk4.1awk版本4.2工作原理4.3工作流程4.4运行模式…

搜维尔科技:Manus VR数据手套-适用于机器人、人工智能和机器学习解决方案

在劳动力短缺和工作环境日益严峻的今天,机器人技术正成为解决这些复杂问题的关键。MANUS™ 手指捕捉技术,结合先进的量子追踪技术,为机器人的精确操作和远程控制提供了准确且先进的解决方案。 技术亮点 实时数据捕捉:通过Quantum…

数学强化✨张宇18讲+1000题45天带刷计划

张宇25版18讲加起来一共656页,是以前的2倍内容,课时量页直接翻倍! 你以为张宇是把强化内容给重新讲了一遍吗?并不是,张宇往年的的强化内容放在了25版的基础部分来讲,这就直接导致张宇基础30讲课时量页跟着…

视频美颜SDK技术揭秘:如何在直播中实现实时美颜

为了满足观众对视觉效果的追求,视频美颜SDK(软件开发工具包)应运而生。今天小编将揭示视频美颜SDK技术,探讨它是如何在直播中实现实时美颜效果的。 一、视频美颜SDK的基本原理 视频美颜SDK是一种专为视频直播应用设计的软件工具…

电子级异丙醇的应用以及电子级异丙醇的提纯

电子级异丙醇是一种极高纯度的异丙醇(Isopropyl Alcohol, IPA),专为电子和其他高科技产业中对清洁度和纯度有严格要求的应用而设计。它经过特殊的精炼和过滤工艺,以去除水分、杂质、颗粒物以及金属离子,确保其具备超低…

最优化(12):约束优化算法

本章主要讲解罚函数法和增广拉格朗日函数法。

微信静默授权,配置redirect_uri,路径

微信静默授权,配置redirect_uri,路径 1.登录微信公众号 2.进入:https://mp.weixin.qq.com/cgi-bin/settingpage?tsetting/function&actionfunction&token1764020234&langzh_CN

2/100数据分析实战项目_商城销售数据分析_Python+帆软BI

前言 商城销售数据分析 数据源:https://www.heywhale.com/mw/project/5f7f0c07fab2e800300e51e4/content BI展示http://localhost:37799/webroot/decision/link/xItL 密码: a600【链接失效:2024年10月31日】 1. 销售数据分析 销售数据分析一般分析什么数据&#x…

C#调试与VS技巧、注释规范等

C#高级调试与VS技巧 断点条件断点联动断点断点详细信息显示并输出 VS技巧常用快捷键保存代码段设置自己的代码命名规则智能显示当前代码所处的Scope固定的选项卡另外起一行竖向选项卡 C#规范注释///自动生成注释para另起一行,see指向符号(可跳转),code插…

WPF的5种绑定模式

WPF的5种绑定模式 WPF的5种绑定模式演示效果XAML WPF的5种绑定模式 OneWay(源变就更新目标属性)TwoWay(源变就更新目标并且目标变就更新源)OneTime(只根据源来设置目标,以后都不会变)OneWayToS…

科普文:Lombok使用及工作原理详解

1. 概叙 Lombok是什么? Project Lombok 是一个 JAVA 库,它可以自动插入编辑器和构建工具,为您的 JAVA 锦上添花。再也不要写另一个 getter/setter 或 equals 等方法,只要有一个注注解,你的类就有一个功能齐全的生成器…

《动手做科研》08. 云端上的深度学习

地址链接:《动手做科研》08. 云端上的深度学习 欢迎加入我的知识星球,定期分享AI论文干货知识! 导读: 当我们开始开发复杂模型时,尝试在本地计算机上训练模型通常不是一个可行的选择,因为我们本地的显存都比较受限制,而…

streamlit安装成功

文章目录 安装streamlit方法1:联网在线安装方法2:离线安装(无网络)安装streamlit 方法1:联网在线安装 在Anaconda的工作环境(或其他虚拟环境或真是环境,均可以)中,安装streamlit: pip install streamlit安装成功后如下图所示: 然后我们测试一下streamlit是否安装…

一文看懂什么是架构

对程序员来说,架构是一个常见词汇。如果想成为一名架构师,对架构概念的理解必须清晰。否则,在制定架构方案时,肯定会漏洞百出,问题频发,这将对你的面试、晋升和团队领导产生负面影响。 我们看下维基百科关…

地方坐标系CAD如何转成标准的国家2000

0序: 现在基本全国范围内都在逐步的应用国家2000了。不分设计院可能由于项目等原因,还在使用地方坐标系,这些地方坐标系的数据很难和标准地图进行叠加。 有些软件提供了4参数的方法来接入地方坐标系的CAD。但不是所有的软件,平台…

用manim创建坐标系

用manim创建坐标系 1.Axes._update_default_configs()的使用 构造函数: static _update_default_configs(default_configs, passed_configs) manim 是一个用于创建数学动画的 Python 库。static _update_default_configs(default_configs, passed_configs) 是 man…

每日一题 ~乘积最大子数组

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/maximum-product-subarray/description/ 题目分析 题目要求找出给定整…