menu E4b9a6's blog
rss_feed
E4b9a6's blog
有善始者实繁,能克终者盖寡。

快速合并多个excel文件

作者:E4b9a6, 创建:2024-11-11, 字数:2792, 已阅:91, 最后更新:2024-11-11

20 个相同内容的 excel 文件想要合并成一个 excel 文件,在网上按照 excel 数据处理方法试了好几次,效果都不太好

想想这是个很简单的活,使用 golang 可以轻松解决

代码打包后的二进制文件如下:

使用方法如下:

  1. 将相同内容的excel放置到同一个目录中,并复制该目录的路径
  2. 双击程序,粘贴路径,回车执行合并
  3. 结果位于excel目录下,名字是merged_output.xlsx

最后,代码部分如下:

Go
package main

import (
    "fmt"
    "log"
    "os"
    "path/filepath"

    "github.com/xuri/excelize/v2"
)

func main() {
    // 让用户输入文件夹路径
    var folderPath string
    fmt.Print("请输入 Excel 文件夹路径: ")
    fmt.Scanln(&folderPath)

    // 获取所有 Excel 文件
    files, err := os.ReadDir(folderPath)
    if err != nil {
    	log.Fatalf("无法读取目录: %v", err)
    }

    // 创建一个新的 Excel 文件
    outputFile := excelize.NewFile()
    var header []string // 用于存储第一份文件的列标题
    rowIndex := 1       // 用于写入输出文件的行索引

    // 遍历所有文件
    for _, file := range files {
    	// 检查文件扩展名是否为 .xlsx
    	if filepath.Ext(file.Name()) == ".xlsx" {
    		filePath := filepath.Join(folderPath, file.Name())
    		fmt.Printf("处理文件: %s\n", filePath)

    		// 打开 Excel 文件
    		f, err := excelize.OpenFile(filePath)
    		if err != nil {
    			log.Printf("无法打开文件 %s: %v", filePath, err)
    			continue
    		}

    		// 获取所有工作表名称
    		sheets := f.GetSheetList()
    		for _, sheet := range sheets {
    			// 读取工作表的所有行
    			rows, err := f.GetRows(sheet)
    			if err != nil {
    				log.Printf("无法读取工作表 %s: %v", sheet, err)
    				continue
    			}

    			// 如果是第一个文件,存储列标题
    			if header == nil {
    				header = rows[0]
    				// 在输出文件中写入列标题
    				if err := outputFile.SetSheetRow("Sheet1", fmt.Sprintf("A%d", rowIndex), &header); err != nil {
    					log.Printf("写入列标题失败: %v", err)
    				}
    				rowIndex++ // 更新行索引
    			} else {
    				// 检查当前文件的列标题是否与第一个文件一致
    				if len(rows[0]) != len(header) {
    					logErrorAndWait(fmt.Sprintf("文件 %s 的列数与第一个文件不一致,期望 %d 列,实际 %d 列", filePath, len(header), len(rows[0])))
    					return
    				}
    				// 检查列名是否一致
    				for i := range header {
    					if header[i] != rows[0][i] {
    						logErrorAndWait(fmt.Sprintf("文件 %s 的列名与第一个文件不一致,期望 %s,实际 %s", filePath, header[i], rows[0][i]))
    						return
    					}
    				}
    			}

    			// 将数据写入新的 Excel 文件(跳过列标题)
    			for rowIndexInFile, row := range rows {
    				if rowIndexInFile == 0 { // 跳过列标题
    					continue
    				}
    				// 写入数据行
    				if err := outputFile.SetSheetRow("Sheet1", fmt.Sprintf("A%d", rowIndex), &row); err != nil {
    					log.Printf("写入行失败: %v", err)
    				}
    				rowIndex++ // 更新行索引
    			}
    		}
    		// 关闭打开的文件
    		f.Close()
    	}
    }

    // 保存合并后的 Excel 文件
    outputPath := filepath.Join(folderPath, "merged_output.xlsx")
    if err := outputFile.SaveAs(outputPath); err != nil {
    	log.Fatalf("无法保存合并后的文件: %v", err)
    }

    fmt.Println("合并完成,输出文件为:", outputPath)

    // 等待用户输入以保持窗口打开
    fmt.Print("按回车键退出...")
    fmt.Scanln() // 等待用户输入
}

// logErrorAndWait 用于打印错误信息并等待用户按下回车键
func logErrorAndWait(message string) {
    fmt.Println("错误:", message)
    fmt.Print("按回车键退出...")
    fmt.Scanln() // 等待用户输入
}

[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
gravatar
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]