package main //import ( // "fmt" // "github.com/xuri/excelize/v2" // "os" // "time" //) // //// ============ main函数 ============ // //func main() { // // 创建Excel管理器 // excelMgr := NewExcelManager() // defer excelMgr.CloseAll() // // fmt.Println("=== Excel文件操作工具 ===") // fmt.Println() // // // 1. 创建测试文件 // fmt.Println("=== 步骤1: 创建测试文件 ===") // createTestFiles() // fmt.Println() // // // 2. 测试基本功能 // fmt.Println("=== 步骤2: 测试基本功能 ===") // testBasicFunctions(excelMgr) // fmt.Println() // // // 3. 测试WriteData函数 // fmt.Println("=== 步骤3: 测试WriteData函数 ===") // testWriteDataFunction(excelMgr) // fmt.Println() // // // 4. 测试SearchRowData函数 // fmt.Println("=== 步骤4: 测试SearchRowData函数 ===") // testSearchRowDataFunction(excelMgr) // fmt.Println() // // // //// 5. 测试CreateAndWrite函数 // fmt.Println("=== 步骤5: 测试CreateAndWrite函数 ===") // testCreateAndWriteFunction(excelMgr) // fmt.Println() // // //// 3. 测试合并功能(包含源文件和序号) // //fmt.Println("=== 步骤3: 测试合并功能(包含源文件和序号)===") // //start := time.Now() // //mergeConfig := MergeConfig{ // // SourceDir: ".", // // OutputFile: "excel/merged_with_info.xlsx", // // SheetName: "合并数据", // // SourceSheet: "员工数据", // // IncludeHeaders: true, // // SkipEmptyRows: false, // // FilePattern: "excel/data*.xlsx", // // AddSourceColumn: false, // // AddIndexColumn: false, // //} // // // //err := excelMgr.MergeExcelFiles(mergeConfig) // //if err != nil { // // fmt.Printf("合并失败: %v\n", err) // //} else { // // elapsed := time.Since(start) // // fmt.Printf("合并完成,耗时: %v\n", elapsed) // //} // //fmt.Println() // // //// 4. 测试并行合并 // //fmt.Println("=== 步骤4: 测试并行合并 ===") // //start = time.Now() // //parallelConfig := MergeConfig{ // // SourceDir: ".", // // OutputFile: "excel/merged_parallel.xlsx", // // SheetName: "并行合并数据", // // SourceSheet: "员工数据", // // IncludeHeaders: true, // // SkipEmptyRows: false, // // FilePattern: "excel/data*.xlsx", // // AddSourceColumn: false, // // AddIndexColumn: false, // //} // // // //err = excelMgr.MergeExcelFilesParallel(parallelConfig, 2) // //if err != nil { // // fmt.Printf("并行合并失败: %v\n", err) // //} else { // // elapsed := time.Since(start) // // fmt.Printf("并行合并完成,耗时: %v\n", elapsed) // //} // // //// 5. 测试按列合并 // //fmt.Println("=== 步骤5: 测试按列合并 ===") // //start = time.Now() // //columnConfig := MergeConfig{ // // SourceDir: ".", // // OutputFile: "merged_by_column.xlsx", // // SheetName: "按列合并", // // SourceSheet: "员工数据", // // IncludeHeaders: false, // // MergeByColumn: true, // // FilePattern: "data*.xlsx", // //} // // // //err = excelMgr.MergeByColumn(columnConfig) // //if err != nil { // // fmt.Printf("按列合并失败: %v\n", err) // //} else { // // elapsed := time.Since(start) // // fmt.Printf("按列合并完成,耗时: %v\n", elapsed) // //} // //fmt.Println() // // // 6. 测试合并指定文件 // fmt.Println("=== 步骤6: 测试合并指定文件 ===") // start := time.Now() // specificConfig := MergeConfig{ // SpecificFiles: []string{"excel/data1.xlsx", "excel/data3.xlsx"}, // OutputFile: "excel/merged_specific.xlsx", // SheetName: "指定文件合并", // SourceSheet: "员工数据", // IncludeHeaders: true, // SkipEmptyRows: false, // AddSourceColumn: false, // AddIndexColumn: false, // } // // err := excelMgr.MergeExcelFiles(specificConfig) // if err != nil { // fmt.Printf("指定文件合并失败: %v\n", err) // } else { // elapsed := time.Since(start) // fmt.Printf("指定文件合并完成,耗时: %v\n", elapsed) // } // fmt.Println() // // //// 7. 测试合并多sheet文件 // //fmt.Println("=== 步骤7: 测试合并多sheet文件 ===") // //err = createMultiSheetFile() // //if err != nil { // // fmt.Printf("创建多sheet文件失败: %v\n", err) // // return // //} // // // //start = time.Now() // //err = excelMgr.MergeSheetsInSameFile("multi_sheet.xlsx", "merged_sheets.xlsx", "所有Sheet数据") // //if err != nil { // // fmt.Printf("合并sheet失败: %v\n", err) // //} else { // // elapsed := time.Since(start) // // fmt.Printf("合并sheet完成,耗时: %v\n", elapsed) // //} // //fmt.Println() // // // 8. 清理测试文件 // //fmt.Println("=== 步骤8: 清理测试文件 ===") // //cleanupTestFiles() //} // //// 测试基本功能 //func testBasicFunctions(em *ExcelManager) { // // 测试读取数据 // rows, err := em.ReadData("excel/data1.xlsx", "员工数据") // if err != nil { // fmt.Printf("读取数据失败: %v\n", err) // return // } // fmt.Printf("data1.xlsx 有 %d 行数据\n", len(rows)) // // // 测试搜索功能 // results, err := em.SearchByKeyword("excel/data1.xlsx", "员工数据", "员工") // if err != nil { // fmt.Printf("搜索失败: %v\n", err) // } else { // fmt.Printf("找到包含'员工'的 %d 个结果\n", len(results)) // } // // // 测试追加数据 // newRow := []interface{}{999, "测试员工", 30, "测试部", "2023-12-01", 20000} // err = em.AppendData("excel/data1.xlsx", "员工数据", newRow) // if err != nil { // fmt.Printf("追加数据失败: %v\n", err) // } else { // fmt.Println("追加数据成功") // } //} // ////// 测试WriteData函数 - 从最大行后面加入新数据 ////func testWriteDataFunction(em *ExcelManager) { //// // 1. 首先读取现有文件获取最大行数 //// fmt.Println("1. 读取现有文件获取最大行数:") //// rows, err := em.ReadData("excel/data1.xlsx", "员工数据") //// if err != nil { //// fmt.Printf("读取数据失败: %v\n", err) //// return //// } //// //// maxRow := len(rows) //// fmt.Printf(" 文件当前有 %d 行数据\n", maxRow) //// //// // 显示最后几行数据 //// if maxRow > 0 { //// showRows := 3 //// if maxRow < showRows { //// showRows = maxRow //// } //// fmt.Printf(" 最后%d行数据预览:\n", showRows) //// for i := maxRow - showRows; i < maxRow; i++ { //// fmt.Printf(" 第%d行: %v\n", i+1, rows[i]) //// } //// } //// //// // 2. 在最大行后面添加新数据 //// fmt.Println("\n2. 在最大行后面添加新数据:") //// //// // 计算新数据开始的行号 //// // 注意:Excel行号从1开始,但rows长度已经包含了所有行 //// startRow := maxRow + 1 //// //// // 准备要添加的新数据(从startRow开始) //// newData := make(map[string]interface{}) //// //// // 添加第1条新记录(在startRow行) //// newData[fmt.Sprintf("A%d", startRow)] = maxRow + 1 //// newData[fmt.Sprintf("B%d", startRow)] = "新增员工1" //// newData[fmt.Sprintf("C%d", startRow)] = 35 //// newData[fmt.Sprintf("D%d", startRow)] = "研发部" //// newData[fmt.Sprintf("E%d", startRow)] = time.Now().Format("2006-01-02") //// newData[fmt.Sprintf("F%d", startRow)] = 25000 //// //// // 添加第2条新记录(在startRow+1行) //// newData[fmt.Sprintf("A%d", startRow+1)] = maxRow + 2 //// newData[fmt.Sprintf("B%d", startRow+1)] = "新增员工2" //// newData[fmt.Sprintf("C%d", startRow+1)] = 28 //// newData[fmt.Sprintf("D%d", startRow+1)] = "测试部" //// newData[fmt.Sprintf("E%d", startRow+1)] = time.Now().Format("2006-01-02") //// newData[fmt.Sprintf("F%d", startRow+1)] = 18000 //// //// // 添加第3条新记录(在startRow+2行) //// newData[fmt.Sprintf("A%d", startRow+2)] = maxRow + 3 //// newData[fmt.Sprintf("B%d", startRow+2)] = "新增员工3" //// newData[fmt.Sprintf("C%d", startRow+2)] = 32 //// newData[fmt.Sprintf("D%d", startRow+2)] = "运维部" //// newData[fmt.Sprintf("E%d", startRow+2)] = time.Now().Format("2006-01-02") //// newData[fmt.Sprintf("F%d", startRow+2)] = 22000 //// //// fmt.Printf(" 将在第%d行开始添加3条新记录\n", startRow) //// //// // 使用WriteData写入新数据 //// err = em.WriteData("excel/data1.xlsx", "员工数据", newData) //// if err != nil { //// fmt.Printf("写入新数据失败: %v\n", err) //// return //// } //// //// fmt.Println(" 写入新数据成功") //// //// // 3. 验证添加结果 //// fmt.Println("\n3. 验证添加结果:") //// //// // 重新读取文件 //// rows, err = em.ReadData("excel/data1.xlsx", "员工数据") //// if err != nil { //// fmt.Printf("重新读取数据失败: %v\n", err) //// return //// } //// //// newMaxRow := len(rows) //// fmt.Printf(" 添加后文件有 %d 行数据,增加了 %d 行\n", newMaxRow, newMaxRow-maxRow) //// //// // 显示新增的几行数据 //// if newMaxRow > maxRow { //// addedRows := newMaxRow - maxRow //// fmt.Printf(" 新增的%d行数据:\n", addedRows) //// for i := maxRow; i < newMaxRow; i++ { //// fmt.Printf(" 第%d行: %v\n", i+1, rows[i]) //// } //// } //// //// // 4. 测试在空文件的最大行后添加数据 //// fmt.Println("\n4. 测试在空文件的最大行后添加数据:") //// //// // 创建一个新的空Excel文件 //// emptyData := [][]interface{}{ //// {"ID", "Name", "Value"}, // 只有表头 //// } //// //// // 先创建只有表头的文件 //// emptyErr := em.CreateAndWrite("excel/empty_test.xlsx", "测试数据", emptyData) //// if emptyErr != nil { //// fmt.Printf("创建空文件失败: %v\n", emptyErr) //// } else { //// fmt.Println(" 创建空文件成功") //// //// // 读取空文件 //// emptyRows, readErr := em.ReadData("excel/empty_test.xlsx", "测试数据") //// if readErr != nil { //// fmt.Printf("读取空文件失败: %v\n", readErr) //// } else { //// emptyMaxRow := len(emptyRows) //// fmt.Printf(" 空文件有 %d 行数据\n", emptyMaxRow) //// //// // 在空文件的最大行后添加数据 //// emptyNewData := make(map[string]interface{}) //// //// // 由于只有表头,所以从第2行开始添加 //// emptyStartRow := emptyMaxRow + 1 //// //// // 添加测试数据 //// emptyNewData[fmt.Sprintf("A%d", emptyStartRow)] = 1 //// emptyNewData[fmt.Sprintf("B%d", emptyStartRow)] = "测试项目1" //// emptyNewData[fmt.Sprintf("C%d", emptyStartRow)] = 100.5 //// //// emptyNewData[fmt.Sprintf("A%d", emptyStartRow+1)] = 2 //// emptyNewData[fmt.Sprintf("B%d", emptyStartRow+1)] = "测试项目2" //// emptyNewData[fmt.Sprintf("C%d", emptyStartRow+1)] = 200.75 //// //// fmt.Printf(" 将在空文件的第%d行开始添加2条记录\n", emptyStartRow) //// //// // 写入数据 //// writeErr := em.WriteData("excel/empty_test.xlsx", "测试数据", emptyNewData) //// if writeErr != nil { //// fmt.Printf(" 向空文件写入数据失败: %v\n", writeErr) //// } else { //// fmt.Println(" 向空文件写入数据成功") //// //// // 验证结果 //// finalRows, finalErr := em.ReadData("excel/empty_test.xlsx", "测试数据") //// if finalErr != nil { //// fmt.Printf(" 验证数据失败: %v\n", finalErr) //// } else { //// finalRowCount := len(finalRows) //// fmt.Printf(" 最终文件有 %d 行数据:\n", finalRowCount) //// //// for i, row := range finalRows { //// fmt.Printf(" 第%d行: %v\n", i+1, row) //// } //// } //// } //// } //// } //// //// // 5. 测试替换现有行的数据 //// fmt.Println("\n5. 测试替换现有行的数据:") //// //// // 替换第2行的部分数据 //// replaceData := map[string]interface{}{ //// "B2": "修改后的姓名", //// "D2": "修改后的部门", //// "F2": 30000, // 修改薪资 //// } //// //// fmt.Println(" 将修改第2行的数据:") //// fmt.Println(" B2: '修改后的姓名'") //// fmt.Println(" D2: '修改后的部门'") //// fmt.Println(" F2: 30000") //// //// replaceErr := em.WriteData("excel/data1.xlsx", "员工数据", replaceData) //// if replaceErr != nil { //// fmt.Printf(" 修改数据失败: %v\n", replaceErr) //// } else { //// fmt.Println(" 修改数据成功") //// //// // 验证修改结果 //// verifyRows, verifyErr := em.ReadData("excel/data1.xlsx", "员工数据") //// if verifyErr != nil { //// fmt.Printf(" 验证修改失败: %v\n", verifyErr) //// } else if len(verifyRows) >= 2 { //// fmt.Printf(" 修改后的第2行数据: %v\n", verifyRows[1]) //// } //// } ////} // //// 测试SearchRowData函数 //func testSearchRowDataFunction(em *ExcelManager) { // fmt.Println("1. 测试搜索包含'员工'的行:") // rows, err := em.SearchRowData("excel/data1.xlsx", "员工数据", "员工") // if err != nil { // fmt.Printf("搜索行数据失败: %v\n", err) // } else { // fmt.Printf("找到 %d 行包含'员工':\n", len(rows)) // for i, row := range rows { // fmt.Printf(" 第%d行: %v\n", i+1, row) // } // } // // fmt.Println("\n2. 测试搜索包含'技术部'的行:") // rows, err = em.SearchRowData("excel/data1.xlsx", "员工数据", "技术部") // if err != nil { // fmt.Printf("搜索行数据失败: %v\n", err) // } else { // fmt.Printf("找到 %d 行包含'技术部':\n", len(rows)) // for i, row := range rows { // fmt.Printf(" 第%d行: %v\n", i+1, row) // } // } // // fmt.Println("\n3. 测试搜索包含'30000'的行:") // rows, err = em.SearchRowData("excel/data1.xlsx", "员工数据", "30000") // if err != nil { // fmt.Printf("搜索行数据失败: %v\n", err) // } else { // fmt.Printf("找到 %d 行包含'30000':\n", len(rows)) // for i, row := range rows { // fmt.Printf(" 第%d行: %v\n", i+1, row) // } // } // // fmt.Println("\n4. 测试搜索不存在的关键词:") // rows, err = em.SearchRowData("excel/data1.xlsx", "员工数据", "不存在的关键词") // if err != nil { // fmt.Printf("搜索行数据失败: %v\n", err) // } else { // fmt.Printf("找到 %d 行包含'不存在的关键词'\n", len(rows)) // if len(rows) == 0 { // fmt.Println(" (正确: 没有找到匹配的行)") // } // } //} // //// 测试CreateAndWrite函数 //func testCreateAndWriteFunction(em *ExcelManager) { // fmt.Println("1. 测试创建新文件并写入数据:") // // //// 准备测试数据 // //testData := [][]string{}{ // // {"序号", "产品名称", "价格", "库存", "类别"}, // // {1, "笔记本电脑", 6999.99, 50, "电子产品"}, // // {2, "智能手机", 3999.99, 100, "电子产品"}, // // {3, "办公椅", 899.99, 30, "办公家具"}, // // {4, "台灯", 199.99, 80, "家居用品"}, // // {5, "书籍", 59.99, 200, "文化用品"}, // // {6, "水杯", 39.99, 150, "日用品"}, // // {7, "背包", 299.99, 60, "箱包"}, // // {8, "鼠标", 99.99, 120, "电子产品"}, // // {9, "键盘", 199.99, 70, "电子产品"}, // // {10, "显示器", 1299.99, 40, "电子产品"}, // //} // // err := em.CreateAndWrite("excel/test_create.xlsx", "产品数据", testData) // if err != nil { // fmt.Printf("创建并写入文件失败: %v\n", err) // } else { // fmt.Println("创建并写入文件成功") // // // 验证文件 // if _, err := os.Stat("excel/test_create.xlsx"); err == nil { // fmt.Println("文件创建成功: excel/test_create.xlsx") // // rows, err := em.ReadData("excel/test_create.xlsx", "产品数据") // if err != nil { // fmt.Printf("读取文件失败: %v\n", err) // } else { // fmt.Printf("文件有 %d 行数据:\n", len(rows)) // // // 显示前5行 // limit := 5 // if len(rows) < limit { // limit = len(rows) // } // // fmt.Println(" 前5行数据:") // for i := 0; i < limit; i++ { // fmt.Printf(" 第%d行: %v\n", i+1, rows[i]) // } // // if len(rows) > limit { // fmt.Printf(" ... 还有 %d 行数据\n", len(rows)-limit) // } // } // // // 测试搜索功能 // fmt.Println("\n2. 在新建文件中测试搜索:") // searchResults, err := em.SearchByKeyword("excel/test_create.xlsx", "产品数据", "电子") // if err != nil { // fmt.Printf("搜索失败: %v\n", err) // } else { // fmt.Printf("找到 %d 个包含'电子'的单元格:\n", len(searchResults)) // for i, result := range searchResults { // fmt.Printf(" %d. %s\n", i+1, result) // } // } // // // 测试行搜索 // fmt.Println("\n3. 在新建文件中测试行搜索:") // rowResults, err := em.SearchRowData("excel/test_create.xlsx", "产品数据", "电子") // if err != nil { // fmt.Printf("行搜索失败: %v\n", err) // } else { // fmt.Printf("找到 %d 行包含'电子':\n", len(rowResults)) // for i, row := range rowResults { // fmt.Printf(" 第%d行: %v\n", i+1, row) // } // } // } // } //} // //// 创建测试文件 //func createTestFiles() { // testFiles := []string{ // "excel/data1.xlsx", // "excel/data2.xlsx", // "excel/data3.xlsx", // } // // for i, filename := range testFiles { // data := [][]interface{}{ // {"ID", "姓名", "年龄", "部门", "入职日期", "薪资"}, // {i*100 + 1, fmt.Sprintf("员工%d", i*3+1), 25 + i, "技术部", "2023-01-15", 15000 + i*1000}, // {i*100 + 2, fmt.Sprintf("员工%d", i*3+2), 28 + i, "市场部", "2023-02-20", 12000 + i*1000}, // {i*100 + 3, fmt.Sprintf("员工%d", i*3+3), 32 + i, "销售部", "2023-03-10", 18000 + i*1000}, // {i*100 + 4, fmt.Sprintf("员工%d", i*3+4), 26 + i, "人事部", "2023-04-05", 10000 + i*1000}, // } // err := createExcelFile(filename, "员工数据", data) // if err != nil { // fmt.Printf("创建文件 %s 失败: %v\n", filename, err) // return // } // fmt.Printf("创建文件: %s (共%d行数据)\n", filename, len(data)) // } //} // //// 创建多sheet测试文件 //func createMultiSheetFile() error { // file := excelize.NewFile() // defer file.Close() // // // Sheet1 // file.NewSheet("部门数据") // data1 := [][]interface{}{ // {"部门", "人数", "预算"}, // {"技术部", 50, 1000000}, // {"市场部", 30, 800000}, // {"销售部", 40, 900000}, // } // writeDataToSheet(file, "部门数据", data1) // // // Sheet2 // file.NewSheet("项目数据") // data2 := [][]interface{}{ // {"项目", "负责人", "进度", "预算"}, // {"项目A", "张三", "80%", 500000}, // {"项目B", "李四", "60%", 300000}, // {"项目C", "王五", "90%", 400000}, // } // writeDataToSheet(file, "项目数据", data2) // // // Sheet3 // file.NewSheet("财务数据") // data3 := [][]interface{}{ // {"月份", "收入", "支出", "利润"}, // {"1月", 500000, 300000, 200000}, // {"2月", 550000, 320000, 230000}, // {"3月", 600000, 350000, 250000}, // } // writeDataToSheet(file, "财务数据", data3) // // // 删除默认的Sheet1 // file.DeleteSheet("Sheet1") // // return file.SaveAs("multi_sheet.xlsx") //} // //// 写入数据到sheet //func writeDataToSheet(file *excelize.File, sheet string, data [][]interface{}) { // for rowIndex, row := range data { // for colIndex, value := range row { // cell, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1) // file.SetCellValue(sheet, cell, value) // } // } //} // //// 创建Excel文件 //func createExcelFile(filename, sheet string, data [][]interface{}) error { // file := excelize.NewFile() // defer file.Close() // // // 删除默认的Sheet1 // file.DeleteSheet("Sheet1") // // // 创建新sheet // sheetIndex, err := file.NewSheet(sheet) // if err != nil { // return err // } // file.SetActiveSheet(sheetIndex) // // // 写入数据 // for rowIndex, row := range data { // for colIndex, value := range row { // cell, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1) // file.SetCellValue(sheet, cell, value) // } // } // // return file.SaveAs(filename) //} // //// 清理测试文件 //func cleanupTestFiles() { // filesToClean := []string{ // "data1.xlsx", // "data2.xlsx", // "data3.xlsx", // "merged_with_info.xlsx", // "merged_parallel.xlsx", // "merged_by_column.xlsx", // "merged_specific.xlsx", // "multi_sheet.xlsx", // "merged_sheets.xlsx", // } // // for _, file := range filesToClean { // if _, err := os.Stat(file); err == nil { // os.Remove(file) // fmt.Printf("删除: %s\n", file) // } // } //}