news 2026/4/18 13:58:54

go语言合并两个excel的sheet为一个excel

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
go语言合并两个excel的sheet为一个excel

在 Go 语言中合并两个 Excel 文件的 sheet,推荐使用excelize库(功能强大且活跃维护)。以下是完整解决方案,包含多种场景:

一、安装依赖

bash

复制

go get github.com/xuri/excelize/v2

二、场景 1:两个 Sheet 合并到新文件(不同 Sheet)

file1.xlsx的 Sheet1 和file2.xlsx的 Sheet1 合并到merged.xlsx的两个独立 Sheet 中。

go

复制

package main import ( "fmt" "github.com/xuri/excelize/v2" ) func main() { // 1. 打开源文件 file1, err := excelize.OpenFile("file1.xlsx") if err != nil { panic(err) } defer file1.Close() file2, err := excelize.OpenFile("file2.xlsx") if err != nil { panic(err) } defer file2.Close() // 2. 创建新文件 merged := excelize.NewFile() streamWriter, err := merged.NewStreamWriter("Sheet1") if err != nil { panic(err) } // 3. 复制第一个文件的 Sheet1 copySheet(file1, "Sheet1", merged, "Sheet1") // 4. 添加第二个 Sheet 并复制 merged.NewSheet("Sheet2") copySheet(file2, "Sheet1", merged, "Sheet2") // 5. 删除默认 Sheet merged.DeleteSheet("Sheet1") // 6. 保存 if err := merged.SaveAs("merged.xlsx"); err != nil { panic(err) } fmt.Println("合并成功!") } // copySheet 复制整个 Sheet 的内容 func copySheet(src *excelize.File, srcSheet string, dst *excelize.File, dstSheet string) { // 获取源 Sheet 所有单元格 rows, err := src.GetRows(srcSheet) if err != nil { panic(err) } // 遍历并复制数据 for rowIdx, row := range rows { for colIdx, cellValue := range row { // 转换列索引为字母 (0 -> A, 1 -> B) colName, _ := excelize.ColumnNumberToName(colIdx + 1) cellAxis := fmt.Sprintf("%s%d", colName, rowIdx+1) // 设置单元格值 dst.SetCellValue(dstSheet, cellAxis, cellValue) } } // 复制列宽 cols, err := src.GetCols(srcSheet) if err != nil { return } for colIdx := range cols { colName, _ := excelize.ColumnNumberToName(colIdx + 1) width, _ := src.GetColWidth(srcSheet, colName) dst.SetColWidth(dstSheet, colName, colName, width) } }

三、场景 2:两个 Sheet 合并为单个 Sheet(追加数据)

file2.xlsx的数据追加到file1.xlsx的 Sheet 末尾(垂直方向)。

go

复制

package main import ( "fmt" "github.com/xuri/excelize/v2" ) func main() { // 1. 打开主文件(作为基础) mainFile, err := excelize.OpenFile("file1.xlsx") if err != nil { panic(err) } defer mainFile.Close() // 2. 打开要合并的文件 mergeFile, err := excelize.OpenFile("file2.xlsx") if err != nil { panic(err) } defer mergeFile.Close() // 3. 获取主文件Sheet1的最后一行 rows, _ := mainFile.GetRows("Sheet1") lastRow := len(rows) + 1 // 追加的起始行 // 4. 获取合并文件的行(可选择跳过表头) mergeRows, _ := mergeFile.GetRows("Sheet1") // 假设第一行是表头,从第二行开始复制 startRow := 2 if len(mergeRows) <= 1 { startRow = 0 // 如果没有表头,全部复制 } // 5. 追加数据 for rowIdx := startRow; rowIdx < len(mergeRows); rowIdx++ { row := mergeRows[rowIdx] for colIdx, cellValue := range row { colName, _ := excelize.ColumnNumberToName(colIdx + 1) cellAxis := fmt.Sprintf("%s%d", colName, lastRow) mainFile.SetCellValue("Sheet1", cellAxis, cellValue) } lastRow++ } // 6. 保存 if err := mainFile.SaveAs("merged_single_sheet.xlsx"); err != nil { panic(err) } fmt.Println("合并成功!数据已追加到单个Sheet") }

四、场景 3:高级版(保留样式、公式、图片)

go

复制

package main import ( "fmt" "github.com/xuri/excelize/v2" ) func mergeWithStyle() { file1, _ := excelize.OpenFile("file1.xlsx") file2, _ := excelize.OpenFile("file2.xlsx") merged := excelize.NewFile() // 复制 Sheet1 并保留样式 copySheetWithStyle(file1, "Sheet1", merged, "File1_Data") // 复制 Sheet2 并保留样式 copySheetWithStyle(file2, "Sheet1", merged, "File2_Data") merged.SaveAs("merged_with_style.xlsx") } // copySheetWithStyle 高级复制(保留样式) func copySheetWithStyle(src *excelize.File, srcSheet string, dst *excelize.File, dstSheet string) { index, _ := dst.NewSheet(dstSheet) // 获取源 Sheet 所有单元格 rows, _ := src.GetRows(srcSheet, excelize.Options{ RawCellValue: true, }) for rIdx, row := range rows { for cIdx, cellValue := range row { colName, _ := excelize.ColumnNumberToName(cIdx + 1) cellAxis := fmt.Sprintf("%s%d", colName, rIdx+1) // 复制值 dst.SetCellValue(dstSheet, cellAxis, cellValue) // 复制样式 styleID, _ := src.GetCellStyle(srcSheet, cellAxis) dst.SetCellStyle(dstSheet, cellAxis, cellAxis, styleID) } } // 激活 Sheet dst.SetActiveSheet(index) }

五、关键注意事项

1.大数据量处理

对于超过 10 万行的数据,使用流式写入避免内存溢出:

go

复制

func streamMerge() { file1, _ := excelize.OpenFile("file1.xlsx") merged := excelize.NewFile() sw, _ := merged.NewStreamWriter("Sheet1") rows, _ := file1.GetRows("Sheet1") for rIdx, row := range rows { cell, _ := excelize.CoordinatesToCellName(1, rIdx+1) sw.SetRow(cell, []interface{}{row}) } sw.Flush() merged.SaveAs("stream_merged.xlsx") }

2.处理不同 Sheet 名称

通过索引获取 Sheet 名:

go

复制

sheetName := file1.GetSheetName(0) // 获取第一个 Sheet

3.错误处理

生产环境建议完整的错误处理:

go

复制

if err != nil { // 记录日志、回滚操作 log.Printf("Error: %v", err) return }

4.内存优化

  • 使用streamWriter处理大文件

  • 及时调用file.Close()释放资源


六、完整项目示例

复制

project/ ├── main.go ├── file1.xlsx # 源文件1 ├── file2.xlsx # 源文件2 └── go.mod

运行

bash

复制

go mod init excel-merge go get github.com/xuri/excelize/v2 go run main.go

选择适合你场景的方案即可。对于简单数据合并,推荐场景 2;对于需要保留格式的情况,使用场景 3copySheetWithStyle函数。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 1:57:52

解密大数据领域 ClickHouse 的数据分区与索引优化

解密大数据领域 ClickHouse 的数据分区与索引优化 关键词:ClickHouse,数据分区,索引优化,大数据,数据存储,查询性能 摘要:本文深入探讨了大数据领域中 ClickHouse 的数据分区与索引优化技术。首先介绍了 ClickHouse 的背景和数据分区、索引优化的重要性,接着详细阐述了…

作者头像 李华
网站建设 2026/4/18 2:07:09

ViGEmBus虚拟手柄驱动技术配置手册

ViGEmBus虚拟手柄驱动技术配置手册 【免费下载链接】ViGEmBus 项目地址: https://gitcode.com/gh_mirrors/vig/ViGEmBus ViGEmBus作为Windows内核级虚拟游戏控制器模拟框架&#xff0c;通过设备抽象层和协议转换机制实现控制器模拟与输入重定向。本手册将深入解析其技术…

作者头像 李华
网站建设 2026/4/18 2:04:43

Windows平台企业级PDF处理解决方案:零配置部署的技术突破

在当今数字化转型浪潮中&#xff0c;PDF文档处理已成为企业信息化建设的核心环节。然而&#xff0c;传统PDF处理方案在Windows平台上的部署复杂度、依赖管理难度以及性能稳定性问题&#xff0c;始终困扰着技术决策者和开发团队。本文深度剖析基于Poppler的Windows预编译解决方案…

作者头像 李华
网站建设 2026/4/18 3:38:03

NCM音乐格式全面解密:释放被锁定的音频宝藏

NCM音乐格式全面解密&#xff1a;释放被锁定的音频宝藏 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的.ncm格式文件无法在其他播放器播放而烦恼&#xff1f;这些被"加密"的音乐文件就像锁在宝箱里…

作者头像 李华
网站建设 2026/4/18 2:13:30

在Windows 11上构建安卓应用生态圈的完整指南

想要将海量安卓应用无缝集成到您的Windows 11工作环境中吗&#xff1f;微软推出的Windows Subsystem for Android&#xff08;WSA&#xff09;技术让这一切成为可能。这个创新的子系统解决方案为Windows用户打开了一扇通往移动应用世界的大门&#xff0c;让您的PC设备获得前所未…

作者头像 李华