go-do-excel
一、介绍
myBook.xlsx表中,B列是“全部IP地址“,A列是“分发成功的IP地址“,本脚本采用go语言编写,通过读取myBook.xlsx中B列“全部IP地址“和A列“分发成功的IP地址“数据,计算出“分发失败的IP地址“数据,将其写入到C列。
二、编程语言
本脚本在Linux Debian12系统上采用go语言编写。
三、excelize安装教程
1.go获取github.com/xuri/excelize/v2很慢解决方法:
使用国内镜像源,可以配置 Go 使用国内的镜像源,例如使用 Goproxy.cn:
export GOPROXY=https://goproxy.cn,direct
然后再次尝试获取库。
2.使用go get安装excelize(推荐方式):
go get github.com/xuri/excelize/v2
四、源代码
goDoExcel.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
package main import ( "fmt" "strconv" /* go获取github.com/xuri/excelize/v2很慢解决方法: 使用国内镜像源,可以配置 Go 使用国内的镜像源,例如使用 Goproxy.cn: export GOPROXY=https://goproxy.cn,direct 然后再次尝试获取库。 */ //使用go get安装excelize(推荐方式): go get github.com/xuri/excelize/v2 "github.com/xuri/excelize/v2" ) func main() { // 打开 Excel 文件 f, err := excelize.OpenFile("myBook.xlsx") if err != nil { fmt.Println(err) return } // 获取第一个工作表的名称 sheetName := f.GetSheetName(0) //fmt.Println(sheetName) // 读取 A 列和 B 列的数据 rows, err := f.GetRows(sheetName) if err != nil { fmt.Println(err) return } var arrayA, arrayB []string // 跳过标题行(第一行) for i, row := range rows { if i == 0 { continue // 跳过标题行 } if row[0] != "" { arrayA = append(arrayA, row[0]) // 读取 A 列数据,跳过空值 } if row[1] != "" { arrayB = append(arrayB, row[1]) // 读取 B 列数据,跳过空值 } } // 计算数组 A 中在数组 B 中没有的数据,并把它存储到数组arrayC var arrayC []string for _, b := range arrayB { if !contains(arrayA, b) { arrayC = append(arrayC, b) } } // 打印结果 //fmt.Println("分发成功IP地址数量:", arrayA) //fmt.Println("全部IP地址数量:", arrayB) //fmt.Println("分发失败IP地址数量:", arrayC) fmt.Println("分发成功IP地址数量:", len(arrayA)) fmt.Println("全部IP地址数量:", len(arrayB)) fmt.Println("分发失败IP地址数量:", len(arrayC)) // 数组arrayC中写入"myBook.xlsx"表中C列 // 向C1单元格写入标题 err = f.SetCellValue(sheetName, "C1", "分发失败IP地址") if err != nil { fmt.Println(err) return } for i, c := range arrayC { num := int64(i + 2) str := strconv.FormatInt(num, 10) // 10表示十进制 //fmt.Println(str) // 向单元格写入新的值 err = f.SetCellValue(sheetName, "C"+str, c) if err != nil { fmt.Println(err) return } } // 保存到原文件 if err := f.Save(); err != nil { fmt.Println(err) return } fmt.Println("文件已保存到 myBook.xlsx") } // contains 检查字符串是否在切片中 func contains(slice []string, str string) bool { for _, item := range slice { if item == str { return true } } return false } |
五、打包go项目
在使用 Go 打包项目时,将依赖一起打包是一个常见的需求,这样可以确保在其他机器上运行时不会因为缺少依赖而出错。以下是一些方法来实现将依赖一起打包:
方法一:使用 Go Modules
从 Go 1.11 开始,Go 引入了模块(Go Modules)来管理依赖。使用 Go Modules 可以确保所有依赖都被正确打包和部署。
1.初始化模块
在项目根目录下运行以下命令初始化模块:
1 2 |
go mod init <module_name> |
例如:
1 2 |
go mod init gitee.com/datutu2015/go-do-excel |
下面命令可以整理依赖,添加新依赖或删除不需要的依赖。
1 2 |
go mod tidy |
2.添加依赖
在代码中导入所需的包,Go 会自动下载并管理这些依赖。例如:
1 2 3 4 5 6 |
import ( "fmt" "strconv" "github.com/xuri/excelize/v2" ) |
3.编译项目
在项目根目录下运行以下命令编译项目:
1 2 |
go build -o myapp main.go |
这将生成一个可执行文件 myapp
,该文件包含了所有静态链接的依赖,在没有安装依赖的系统上,只要操作系统和架构与编译时的目标一致,就可以直接运行。
4.打包
将生成的可执行文件打包成一个压缩包:
1 2 |
tar -czvf myapp.tar.gz myapp |
方法二:使用静态链接
静态链接可以将所有依赖库直接嵌入到可执行文件中,这样生成的可执行文件是独立的,可以在没有安装这些库的系统上运行。
1.编译项目
使用以下命令编译项目,确保使用静态链接:
1).指定目标操作系统linux和amd64架构
1 2 |
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o myapp main.go |
CGO_ENABLED=0
:禁用 CGO,确保生成的可执行文件是静态链接的。-
GOOS=linux
和GOARCH=amd64
:指定目标操作系统linux和amd64架构。 -
2).指定目标操作系统linux和arm64架构
12CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o myapp main.go CGO_ENABLED=0
:禁用 CGO,确保生成的可执行文件是静态链接的。-
GOOS=linux
和GOARCH=arm64
:指定目标操作系统linux和arm64架构。
2.打包
将生成的可执行文件打包成一个压缩包:
1 2 |
tar -czvf myapp.tar.gz myapp |
总结
- 使用 Go Modules:适用于大多数现代 Go 项目,简单且易于管理,在没有安装依赖的系统上,只要操作系统和架构与编译时的目标一致,就可以直接运行。
- 推荐使用静态链接:生成独立的可执行文件,适合在没有安装依赖的系统上运行,它指定目标操作系统和架构。
根据你的具体需求选择合适的方法来将依赖一起打包。
六、使用说明
已打包本脚本“goDoExcel1.0-linux-amd64.tar.gz“和”goDoExcel1.0-linux-arm64.tar.gz”,可以在没有go语言环境和依赖的Linux amd64架构和arm64架构的系统上运行。
例如:
1.解压:
tar -xzvf goDoExcel1.0-linux-amd64.tar.gz
2.进入目录
cd goDoExcel1.0-linux-amd64
3.查看该目录下文件
ls
4.运行可执行程序
./goDoExcel.go
七、源代码和打包可执行程序下载
知识星球:
1 2 3 4 |
https://t.zsxq.com/ht72U https://t.zsxq.com/178qm |
蓝奏云:
1 2 |
https://wwxc.lanzouo.com/iNM4C2wwmwfg |
go mod init <module-name>
知识点:
在 Go 语言的模块化开发中,go mod init <module-name>
是一个非常重要的命令,用于初始化一个新的 Go 模块。下面来详细解释一下 <module-name>
的含义和作用:
1. <module-name>
的定义
<module-name>
是你为当前 Go 模块指定的名称。它通常是一个 唯一的标识符,用来区分不同的模块。模块名称在 Go 的生态系统中非常重要,尤其是在依赖管理和版本控制方面。
2. <module-name>
的作用
- 模块路径:
<module-name>
是模块的路径,它在导入模块时被使用。当你在其他项目中导入这个模块时,需要使用这个模块名。例如,如果模块名是github.com/yourusername/yourmodule
,那么在其他项目中导入时,就会写成:12import "github.com/yourusername/yourmodule" - 版本控制:模块名通常包含版本信息,这有助于在不同版本之间进行区分。例如,
github.com/yourusername/yourmodule/v2
表示该模块的第二个主要版本。 -
唯一性:为了确保模块的唯一性,模块名通常包含一个域名或组织名。这样可以避免不同开发者之间的命名冲突。例如,
github.com/yourusername/yourmodule
和github.com/otherusername/yourmodule
是两个不同的模块。
3. <module-name>
的命名规范
- 域名优先:通常以域名开头,例如
github.com
、golang.org
等。这样可以保证模块名的唯一性,避免命名冲突。 - 路径结构:域名后面可以加上项目路径,例如
github.com/yourusername/yourmodule
。这种结构清晰地表明了模块的来源和归属。 - 版本号(可选):如果模块有多个主要版本,可以在模块名中添加版本号,例如
github.com/yourusername/yourmodule/v2
。这有助于在不同版本之间进行区分。
4. 示例
假设你正在开发一个名为 myproject
的项目,并且你的代码托管在 GitHub 上,用户名为 yourusername
。你可以这样初始化模块:
1 2 |
go mod init github.com/yourusername/myproject |
这样,github.com/yourusername/myproject
就是你的模块名。在其他项目中导入这个模块时,就会写成:
1 2 |
import "github.com/yourusername/myproject" |
5. 注意事项
- 模块名的更改:一旦模块初始化后,模块名是不能轻易更改的。如果需要更改模块名,需要重新初始化模块,并更新所有依赖该模块的项目。
- 本地模块:如果你只是在本地开发,没有托管到远程仓库,模块名可以是任意的,但最好还是遵循命名规范,以便将来可能的迁移。
总之,<module-name>
是 Go 模块系统的核心部分,它不仅用于标识模块,还在依赖管理和版本控制中发挥关键作用。