当前位置: 首页 > news >正文

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函数。

http://www.cnnetsun.cn/news/405725.html

相关文章:

  • 阴阳师自动化脚本高效使用全攻略:从入门到精通
  • ViGEmBus终极指南:Windows游戏控制器虚拟化完整解决方案
  • SillyTavern终极指南:打造专业级AI聊天桌面的完整解决方案
  • NCM音乐格式终极解锁指南:3分钟快速解密网易云加密音乐
  • NCM格式转换与音乐处理完整操作指南
  • 猫抓cat-catch终极资源嗅探工具完整使用手册
  • Lucky Draw:打造完美年会抽奖体验的终极开源解决方案
  • 电话号码定位技术:从零开始的完整解决方案
  • QQ音乐加密格式转换工具:qmcdump完整使用指南
  • RePKG终极指南:快速掌握Wallpaper Engine资源管理技巧
  • 网易云音乐NCM文件终极解密教程:一键解锁加密音乐
  • 3分钟搞定Unity游戏翻译:XUnity.AutoTranslator零基础使用指南
  • NCM格式终极解密指南:3种快速解锁方法详解
  • 闲鱼自动化终极指南:一键解放双手,效率提升300%
  • 快速制作B站封面:downkyi工具终极指南
  • ViGEmBus终极指南:轻松搞定Windows游戏控制器虚拟化
  • Linux 调试利器:GDB 全面操作指南
  • 3大场景7步操作:猫抓cat-catch浏览器资源嗅探工具实战指南
  • 3步打造全球化Android应用:从WeChatLuckyMoney看国际化最佳实践
  • 终极年会抽奖系统:5分钟快速部署完整解决方案
  • ncmdump音乐格式转换工具:从加密到通用的完美解密方案
  • GitHub汉化插件终极指南:让GitHub界面全面说中文
  • NVIDIA Profile Inspector:突破显卡性能瓶颈的秘密武器
  • DownKyi视频下载工具:从入门到精通的完整教程
  • 【接口测试】3_持续集成 _Jenkins
  • TCC-G15散热控制:彻底解决Dell游戏本温度过高问题
  • 学长亲荐9个AI论文写作软件,专科生搞定毕业论文不求人!
  • 网易云音乐NCM加密终结者:3秒解锁音乐自由
  • NVIDIA显卡隐藏性能终极挖掘指南:解锁你的游戏新境界
  • 游戏画质革命:DLSS Swapper让你3分钟搞定DLSS版本升级