当前位置: 首页 > 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.jsqmd.com/news/188955/

相关文章:

  • 戴尔G15散热控制终极指南:tcc-g15完整使用教程
  • 【图像处理与ISP技术】像素与图像数字化
  • 英雄联盟自动化工具:如何用5分钟彻底告别繁琐操作
  • 终极B站视频下载神器:DownKyi完整使用教程与性能优化指南
  • [Quicker] 智能窗口布局 - 源码归档
  • 5步搞定B站8K视频下载:DownKyi终极使用指南
  • 网易云音乐NCM文件一键解密终极指南:快速解锁加密音乐
  • DownKyi快速上手:3步完成B站视频高质量下载
  • Unity游戏翻译神器:XUnity自动翻译器深度解析与实战指南
  • ncmdump终极解密:网易云音乐格式转换完全指南
  • ncmdump高效音乐格式转换全攻略:解锁加密音频的无限可能
  • 动态网页爬取,Selenium与Scrapy完整落地(附实战案例)
  • 完全掌握Dell G15散热控制:突破性能瓶颈的三步快速降温方案
  • Universal x86 Tuning Utility:释放硬件潜能的智能调优方案
  • Bili2text深度评测:5大应用场景解锁视频内容价值
  • GitHub中文界面改造指南:让技术平台更懂你的语言
  • Switch手柄电脑适配全攻略:从零开始打造专属游戏体验
  • 英雄联盟智能助手League Akari:全面提升游戏体验的完整指南
  • 终极指南:解锁Switch手柄在PC平台的完整游戏潜能
  • 电话号码定位技术:从零开始的完整解决方案
  • NCM格式解密工具终极指南:轻松解锁网易云音乐加密文件
  • NVIDIA显卡隐藏性能解锁:Profile Inspector新手必读指南
  • 5步快速上手:如何用XUnity自动翻译器让外语游戏秒变中文版
  • ncmdump深度解析:解锁网易云音乐加密格式的终极方案
  • 猫抓浏览器扩展:一键解锁网页视频下载新境界
  • Lucky Draw:如何用开源工具打造完美年会抽奖体验?
  • TranslucentTB终极指南:3步打造完美透明任务栏,彻底告别单调桌面
  • jQuery 过滤
  • 【Week2_Day9】【软件测试学习记录与反思】【SQL查询演练10题、整理思维导图、归纳遇到的问题、记录反思改进】
  • XUnity自动翻译器:Unity游戏实时汉化插件完整指南