1426 lines
37 KiB
Go
1426 lines
37 KiB
Go
package main
|
||
|
||
///*
|
||
//#cgo LDFLAGS: -ldl
|
||
//
|
||
//#include <dlfcn.h>
|
||
//#include <stdlib.h>
|
||
//#include <stdio.h>
|
||
//*/
|
||
//import "C"
|
||
//import (
|
||
// "encoding/csv"
|
||
// "encoding/json"
|
||
// "fmt"
|
||
// "github.com/xuri/excelize/v2"
|
||
// "os"
|
||
// "path/filepath"
|
||
// "sort"
|
||
// "strings"
|
||
// "sync"
|
||
// "unsafe"
|
||
//)
|
||
//
|
||
//// ExcelManager 线程安全的Excel文件管理器
|
||
//type ExcelManager struct {
|
||
// mu sync.RWMutex
|
||
// fileMap map[string]*excelize.File // 存储打开的文件
|
||
//}
|
||
//
|
||
//// MergeConfig 合并配置
|
||
//type MergeConfig struct {
|
||
// SourceDir string // 源目录
|
||
// OutputFile string // 输出文件
|
||
// SheetName string // 目标sheet名称
|
||
// MergeByColumn bool // 是否按列合并(默认按行)
|
||
// IncludeHeaders bool // 是否包含表头(仅第一个文件)
|
||
// SkipEmptyRows bool // 是否跳过空行
|
||
// FilePattern string // 文件匹配模式,如 "*.xlsx"
|
||
// SpecificFiles []string // 指定要合并的文件列表
|
||
// SourceSheet string // 源sheet名称(为空则使用第一个sheet)
|
||
// AddSourceColumn bool // 是否添加源文件列
|
||
// AddIndexColumn bool // 是否添加序号列
|
||
//}
|
||
//
|
||
//// NewExcelManager 创建新的Excel管理器
|
||
//func NewExcelManager() *ExcelManager {
|
||
// return &ExcelManager{
|
||
// fileMap: make(map[string]*excelize.File),
|
||
// }
|
||
//}
|
||
//
|
||
//// ============ 基本Excel操作功能 ============
|
||
//
|
||
//// ReadData 读取Excel数据
|
||
//func (em *ExcelManager) ReadData(filename, sheet string) ([][]string, error) {
|
||
// em.mu.RLock()
|
||
// defer em.mu.RUnlock()
|
||
// fmt.Printf("[DEBUG] ReadData开始: file=%s, sheet=%s\n", filename, sheet)
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
// defer file.Close()
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("读取sheet %s 失败: %v", sheet, err)
|
||
// }
|
||
// fmt.Printf("[DEBUG] 读取的数据:", rows)
|
||
// return rows, nil
|
||
//}
|
||
//
|
||
//// WriteData 写入数据到指定位置
|
||
//func (em *ExcelManager) WriteData(filename, sheet string, data map[string]interface{}) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// // 文件不存在,创建新文件
|
||
// file = excelize.NewFile()
|
||
// file.NewSheet(sheet)
|
||
// } else {
|
||
// // 确保sheet存在
|
||
// index, _ := file.GetSheetIndex(sheet)
|
||
// if index == -1 {
|
||
// file.NewSheet(sheet)
|
||
// }
|
||
// }
|
||
//
|
||
// // 写入数据
|
||
// for cell, value := range data {
|
||
// file.SetCellValue(sheet, cell, value)
|
||
// }
|
||
//
|
||
// // 保存文件
|
||
// return file.SaveAs(filename)
|
||
//}
|
||
//
|
||
//// AppendData 追加数据到末尾
|
||
//func (em *ExcelManager) AppendData(filename, sheet string, rowData []interface{}) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// defer func() {
|
||
// file.SaveAs(filename)
|
||
// file.Close()
|
||
// }()
|
||
//
|
||
// // 确保sheet存在
|
||
// index, _ := file.GetSheetIndex(sheet)
|
||
// if index == -1 {
|
||
// file.NewSheet(sheet)
|
||
// }
|
||
//
|
||
// // 获取当前最大行号
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
//
|
||
// nextRow := len(rows) + 1
|
||
// if len(rows) == 0 {
|
||
// nextRow = 1
|
||
// }
|
||
//
|
||
// // 写入新行
|
||
// for col, value := range rowData {
|
||
// cell, _ := excelize.CoordinatesToCellName(col+1, nextRow)
|
||
// file.SetCellValue(sheet, cell, value)
|
||
// }
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// SearchByKeyword 搜索包含关键字的单元格
|
||
//func (em *ExcelManager) SearchByKeyword(filename, sheet, keyword string) ([]string, error) {
|
||
// em.mu.RLock()
|
||
// defer em.mu.RUnlock()
|
||
//
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
// defer file.Close()
|
||
//
|
||
// var results []string
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
//
|
||
// for rowIndex, row := range rows {
|
||
// for colIndex, cell := range row {
|
||
// if strings.Contains(cell, keyword) {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
|
||
// results = append(results,
|
||
// fmt.Sprintf("位置: %s, 值: %s", cellName, cell))
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
// return results, nil
|
||
//}
|
||
//
|
||
//// SearchRowData 搜索整行包含关键字的行
|
||
//func (em *ExcelManager) SearchRowData(filename, sheet, keyword string) ([][]string, error) {
|
||
// em.mu.RLock()
|
||
// defer em.mu.RUnlock()
|
||
//
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
// defer file.Close()
|
||
//
|
||
// var results [][]string
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
//
|
||
// for _, row := range rows {
|
||
// for _, cell := range row {
|
||
// if strings.Contains(cell, keyword) {
|
||
// results = append(results, row)
|
||
// break
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
// return results, nil
|
||
//}
|
||
//
|
||
//// CreateAndWrite 创建新文件并写入数据
|
||
//func (em *ExcelManager) CreateAndWrite(filename, sheet string, data [][]string) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// // 创建新文件
|
||
// file := excelize.NewFile()
|
||
// defer file.Close()
|
||
//
|
||
// // 如果指定sheet不是"Sheet1",则重命名默认sheet
|
||
// if sheet != "Sheet1" {
|
||
// file.SetSheetName("Sheet1", sheet)
|
||
// }
|
||
//
|
||
// // 写入数据
|
||
// 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)
|
||
//}
|
||
//
|
||
//// CloseAll 关闭所有文件
|
||
//func (em *ExcelManager) CloseAll() error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// var lastErr error
|
||
// for filename, file := range em.fileMap {
|
||
// if err := file.Close(); err != nil {
|
||
// lastErr = err
|
||
// }
|
||
// delete(em.fileMap, filename)
|
||
// }
|
||
// return lastErr
|
||
//}
|
||
//
|
||
//// ============ Excel合并功能 ============
|
||
//
|
||
//// MergeExcelFiles 合并多个Excel文件(批次合并)
|
||
//func (em *ExcelManager) MergeExcelFiles(config MergeConfig) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// // 获取要合并的文件列表
|
||
// filesToMerge, err := em.getFilesToMerge(config)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
//
|
||
// fmt.Printf("开始合并 %d 个文件:\n", len(filesToMerge))
|
||
// for i, file := range filesToMerge {
|
||
// fmt.Printf(" %d. %s\n", i+1, filepath.Base(file))
|
||
// }
|
||
//
|
||
// // 创建新的输出文件
|
||
// outputFile := excelize.NewFile()
|
||
// defer outputFile.Close()
|
||
//
|
||
// // 删除默认的Sheet1
|
||
// outputFile.DeleteSheet("Sheet1")
|
||
//
|
||
// // 创建目标sheet并设置为活动sheet
|
||
// sheetIndex, err := outputFile.NewSheet(config.SheetName)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建sheet失败: %v", err)
|
||
// }
|
||
// outputFile.SetActiveSheet(sheetIndex)
|
||
//
|
||
// currentRow := 1
|
||
// totalRowsMerged := 0
|
||
// fileCount := len(filesToMerge)
|
||
//
|
||
// // 写入表头(如果需要)
|
||
// if config.IncludeHeaders && fileCount > 0 {
|
||
// headers, err := em.readFileHeaders(filesToMerge[0], config.SourceSheet)
|
||
// if err != nil {
|
||
// fmt.Printf("警告: 无法读取第一个文件的表头: %v\n", err)
|
||
// } else {
|
||
// // 添加额外的列(如果需要)
|
||
// colOffset := 0
|
||
// if config.AddIndexColumn {
|
||
// headers = append([]string{"序号"}, headers...)
|
||
// colOffset++
|
||
// }
|
||
// if config.AddSourceColumn {
|
||
// headers = append([]string{"源文件"}, headers...)
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 写入表头
|
||
// for colIndex, header := range headers {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1, currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, header)
|
||
// }
|
||
// currentRow++
|
||
// fmt.Printf("写入表头: %v\n", headers)
|
||
// }
|
||
// }
|
||
//
|
||
// // 合并所有文件
|
||
// for fileIndex, sourceFile := range filesToMerge {
|
||
// rowsMerged, err := em.mergeSingleFile(outputFile, config, sourceFile, fileIndex, fileCount, ¤tRow)
|
||
// if err != nil {
|
||
// fmt.Printf("警告: 合并文件 %s 时出错: %v,跳过\n", sourceFile, err)
|
||
// continue
|
||
// }
|
||
// totalRowsMerged += rowsMerged
|
||
// }
|
||
//
|
||
// // 保存输出文件
|
||
// if err := outputFile.SaveAs(config.OutputFile); err != nil {
|
||
// return fmt.Errorf("保存合并文件失败: %v", err)
|
||
// }
|
||
//
|
||
// fmt.Printf("合并完成!结果保存在: %s\n", config.OutputFile)
|
||
// fmt.Printf("统计信息:\n")
|
||
// fmt.Printf(" - 合并文件数: %d\n", fileCount)
|
||
// fmt.Printf(" - 合并数据行数: %d\n", totalRowsMerged)
|
||
// fmt.Printf(" - 输出文件总行数: %d\n", currentRow-1)
|
||
//
|
||
// // 验证文件是否正确保存
|
||
// if err := em.verifyMergeResult(config.OutputFile, config.SheetName); err != nil {
|
||
// return fmt.Errorf("合并结果验证失败: %v", err)
|
||
// }
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// getFilesToMerge 获取要合并的文件列表
|
||
//func (em *ExcelManager) getFilesToMerge(config MergeConfig) ([]string, error) {
|
||
// var filesToMerge []string
|
||
//
|
||
// if len(config.SpecificFiles) > 0 {
|
||
// filesToMerge = config.SpecificFiles
|
||
// } else if config.SourceDir != "" {
|
||
// pattern := "*.xlsx"
|
||
// if config.FilePattern != "" {
|
||
// pattern = config.FilePattern
|
||
// }
|
||
//
|
||
// files, err := filepath.Glob(filepath.Join(config.SourceDir, pattern))
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("查找文件失败: %v", err)
|
||
// }
|
||
// filesToMerge = files
|
||
// } else {
|
||
// return nil, fmt.Errorf("必须指定SourceDir或SpecificFiles")
|
||
// }
|
||
//
|
||
// if len(filesToMerge) == 0 {
|
||
// return nil, fmt.Errorf("没有找到要合并的Excel文件")
|
||
// }
|
||
//
|
||
// // 按文件名排序
|
||
// sort.Strings(filesToMerge)
|
||
// return filesToMerge, nil
|
||
//}
|
||
//
|
||
//// readFileHeaders 读取文件的表头
|
||
//func (em *ExcelManager) readFileHeaders(filename, sheetName string) ([]string, error) {
|
||
// srcFile, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
// defer srcFile.Close()
|
||
//
|
||
// sourceSheet := em.getSourceSheet(srcFile, sheetName)
|
||
// if sourceSheet == "" {
|
||
// return nil, fmt.Errorf("未找到可用的sheet")
|
||
// }
|
||
//
|
||
// rows, err := srcFile.GetRows(sourceSheet)
|
||
// if err != nil {
|
||
// return nil, err
|
||
// }
|
||
//
|
||
// if len(rows) == 0 {
|
||
// return nil, fmt.Errorf("文件没有数据")
|
||
// }
|
||
//
|
||
// return rows[0], nil
|
||
//}
|
||
//
|
||
//// mergeSingleFile 合并单个文件
|
||
//func (em *ExcelManager) mergeSingleFile(outputFile *excelize.File, config MergeConfig,
|
||
// sourceFile string, fileIndex, fileCount int, currentRow *int) (int, error) {
|
||
//
|
||
// fmt.Printf("\n[%d/%d] 正在处理文件: %s\n", fileIndex+1, fileCount, filepath.Base(sourceFile))
|
||
//
|
||
// // 打开源文件
|
||
// srcFile, err := excelize.OpenFile(sourceFile)
|
||
// if err != nil {
|
||
// return 0, fmt.Errorf("打开文件失败: %v", err)
|
||
// }
|
||
// defer srcFile.Close()
|
||
//
|
||
// // 确定要读取的sheet
|
||
// sourceSheet := em.getSourceSheet(srcFile, config.SourceSheet)
|
||
// if sourceSheet == "" {
|
||
// return 0, fmt.Errorf("未找到可用的sheet")
|
||
// }
|
||
//
|
||
// // 读取源文件数据
|
||
// rows, err := srcFile.GetRows(sourceSheet)
|
||
// if err != nil {
|
||
// return 0, fmt.Errorf("读取数据失败: %v", err)
|
||
// }
|
||
//
|
||
// if len(rows) == 0 {
|
||
// fmt.Printf(" 警告: 文件没有数据,跳过\n")
|
||
// return 0, nil
|
||
// }
|
||
//
|
||
// fmt.Printf(" 读取到 %d 行数据\n", len(rows))
|
||
//
|
||
// rowsMerged := 0
|
||
//
|
||
// // 处理数据行
|
||
// for rowIndex, row := range rows {
|
||
// // 跳过空行
|
||
// if config.SkipEmptyRows && em.isRowEmpty(row) {
|
||
// continue
|
||
// }
|
||
// fmt.Println(rowIndex)
|
||
// // 处理表头(如果是第一个文件且包含表头,第一行已经处理过了)
|
||
// if config.IncludeHeaders && rowIndex == 0 {
|
||
// if fileIndex == 0 {
|
||
// // 第一个文件的表头已处理,跳过
|
||
// continue
|
||
// } else {
|
||
// // 后续文件的表头跳过
|
||
// continue
|
||
// }
|
||
// }
|
||
//
|
||
// // 写入数据行
|
||
// colOffset := 0
|
||
//
|
||
// // 添加序号列
|
||
// if config.AddIndexColumn {
|
||
// cellName, _ := excelize.CoordinatesToCellName(1, *currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, rowsMerged+1)
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 添加源文件列
|
||
// if config.AddSourceColumn {
|
||
// cellName, _ := excelize.CoordinatesToCellName(1+colOffset, *currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, filepath.Base(sourceFile))
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 写入原始数据
|
||
// for colIndex, cell := range row {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1+colOffset, *currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, cell)
|
||
// }
|
||
//
|
||
// rowsMerged++
|
||
// *currentRow++
|
||
// }
|
||
//
|
||
// //// 添加文件分隔信息(如果有数据被合并)
|
||
// //if rowsMerged > 0 {
|
||
// // // 添加分隔行
|
||
// // separatorCell, _ := excelize.CoordinatesToCellName(1, *currentRow)
|
||
// // outputFile.SetCellValue(config.SheetName, separatorCell,
|
||
// // fmt.Sprintf("=== 文件 %d/%d: %s (合并了 %d 行) ===",
|
||
// // fileIndex+1, fileCount, filepath.Base(sourceFile), rowsMerged))
|
||
// // *currentRow++
|
||
// //}
|
||
//
|
||
// fmt.Printf(" 文件处理完成,合并了 %d 行数据\n", rowsMerged)
|
||
// return rowsMerged, nil
|
||
//}
|
||
//
|
||
//// getSourceSheet 获取源sheet名称
|
||
//func (em *ExcelManager) getSourceSheet(file *excelize.File, preferredSheet string) string {
|
||
// if preferredSheet != "" {
|
||
// if index, _ := file.GetSheetIndex(preferredSheet); index != -1 {
|
||
// return preferredSheet
|
||
// }
|
||
// }
|
||
//
|
||
// // 返回第一个sheet
|
||
// sheets := file.GetSheetList()
|
||
// if len(sheets) > 0 {
|
||
// return sheets[0]
|
||
// }
|
||
// return ""
|
||
//}
|
||
//
|
||
//// verifyMergeResult 验证合并结果
|
||
//func (em *ExcelManager) verifyMergeResult(filename, sheet string) error {
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return fmt.Errorf("打开验证文件失败: %v", err)
|
||
// }
|
||
// defer file.Close()
|
||
//
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// return fmt.Errorf("读取sheet失败: %v", err)
|
||
// }
|
||
//
|
||
// fmt.Printf("\n验证结果:\n")
|
||
// fmt.Printf(" 文件: %s\n", filename)
|
||
// fmt.Printf(" Sheet: %s\n", sheet)
|
||
// fmt.Printf(" 总行数: %d\n", len(rows))
|
||
//
|
||
// if len(rows) == 0 {
|
||
// return fmt.Errorf("警告: 合并后的文件没有数据!")
|
||
// }
|
||
//
|
||
// // 显示前5行数据
|
||
// limit := 5
|
||
// if len(rows) < limit {
|
||
// limit = len(rows)
|
||
// }
|
||
//
|
||
// fmt.Printf(" 前%d行数据预览:\n", limit)
|
||
// for i := 0; i < limit; i++ {
|
||
// // 只显示前5列(避免输出过长)
|
||
// previewCols := 5
|
||
// if len(rows[i]) < previewCols {
|
||
// previewCols = len(rows[i])
|
||
// }
|
||
// fmt.Printf(" 第%d行: %v", i+1, rows[i][:previewCols])
|
||
// if len(rows[i]) > previewCols {
|
||
// fmt.Printf(" ... (+%d列)", len(rows[i])-previewCols)
|
||
// }
|
||
// fmt.Println()
|
||
// }
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// MergeExcelFilesParallel 并行合并Excel文件(高性能)
|
||
//func (em *ExcelManager) MergeExcelFilesParallel(config MergeConfig, workers int) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// // 获取要合并的文件列表
|
||
// filesToMerge, err := em.getFilesToMerge(config)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
//
|
||
// fmt.Printf("开始并行合并 %d 个文件,使用 %d 个worker:\n", len(filesToMerge), workers)
|
||
//
|
||
// // 创建通道和等待组
|
||
// fileChan := make(chan fileTask, len(filesToMerge))
|
||
// resultChan := make(chan fileResult, len(filesToMerge))
|
||
// var wg sync.WaitGroup
|
||
//
|
||
// // 启动worker goroutines
|
||
// for i := 0; i < workers; i++ {
|
||
// wg.Add(1)
|
||
// go func(workerID int) {
|
||
// defer wg.Done()
|
||
// for task := range fileChan {
|
||
// fmt.Printf("Worker %d 正在处理: %s (文件 %d/%d)\n",
|
||
// workerID, filepath.Base(task.filename), task.index+1, task.total)
|
||
// data := em.readExcelFileParallel(task.filename, config.SourceSheet)
|
||
// resultChan <- fileResult{
|
||
// filename: task.filename,
|
||
// index: task.index,
|
||
// data: data,
|
||
// }
|
||
// }
|
||
// }(i)
|
||
// }
|
||
//
|
||
// // 发送文件任务到通道
|
||
// for i, file := range filesToMerge {
|
||
// fileChan <- fileTask{
|
||
// filename: file,
|
||
// index: i,
|
||
// total: len(filesToMerge),
|
||
// }
|
||
// }
|
||
// close(fileChan)
|
||
//
|
||
// // 等待所有worker完成
|
||
// go func() {
|
||
// wg.Wait()
|
||
// close(resultChan)
|
||
// }()
|
||
//
|
||
// // 收集结果
|
||
// var results []fileResult
|
||
// for result := range resultChan {
|
||
// results = append(results, result)
|
||
// }
|
||
//
|
||
// // 按文件索引排序
|
||
// sort.Slice(results, func(i, j int) bool {
|
||
// return results[i].index < results[j].index
|
||
// })
|
||
//
|
||
// // 创建新的输出文件
|
||
// outputFile := excelize.NewFile()
|
||
// defer outputFile.Close()
|
||
//
|
||
// // 删除默认的Sheet1
|
||
// outputFile.DeleteSheet("Sheet1")
|
||
//
|
||
// // 创建目标sheet
|
||
// sheetIndex, err := outputFile.NewSheet(config.SheetName)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建sheet失败: %v", err)
|
||
// }
|
||
// outputFile.SetActiveSheet(sheetIndex)
|
||
//
|
||
// // 合并数据
|
||
// currentRow := 1
|
||
// totalRowsMerged := 0
|
||
//
|
||
// // 写入表头(如果需要)
|
||
// headersWritten := false
|
||
// if config.IncludeHeaders && len(results) > 0 {
|
||
// for _, result := range results {
|
||
// if result.data.err == nil && len(result.data.rows) > 0 {
|
||
// headers := result.data.rows[0]
|
||
// // 添加额外的列
|
||
// colOffset := 0
|
||
// if config.AddIndexColumn {
|
||
// headers = append([]string{"序号"}, headers...)
|
||
// colOffset++
|
||
// }
|
||
// if config.AddSourceColumn {
|
||
// headers = append([]string{"源文件"}, headers...)
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 写入表头
|
||
// for colIndex, header := range headers {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1, currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, header)
|
||
// }
|
||
// currentRow++
|
||
// headersWritten = true
|
||
// fmt.Printf("写入表头: %v\n", headers)
|
||
// break // 只取第一个有效文件的表头
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
// // 写入数据
|
||
// for _, result := range results {
|
||
// if result.data.err != nil {
|
||
// fmt.Printf("警告: 文件 %s 处理失败: %v,跳过\n", result.filename, result.data.err)
|
||
// continue
|
||
// }
|
||
//
|
||
// if len(result.data.rows) == 0 {
|
||
// fmt.Printf("警告: 文件 %s 没有数据,跳过\n", result.filename)
|
||
// continue
|
||
// }
|
||
//
|
||
// rowsMerged := 0
|
||
// for rowIndex, row := range result.data.rows {
|
||
// // 跳过表头(如果已经处理过)
|
||
// if config.IncludeHeaders && rowIndex == 0 && headersWritten {
|
||
// continue
|
||
// }
|
||
//
|
||
// // 跳过空行
|
||
// if config.SkipEmptyRows && em.isRowEmpty(row) {
|
||
// continue
|
||
// }
|
||
//
|
||
// // 写入数据行
|
||
// colOffset := 0
|
||
//
|
||
// // 添加序号列
|
||
// if config.AddIndexColumn {
|
||
// cellName, _ := excelize.CoordinatesToCellName(1, currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, totalRowsMerged+1)
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 添加源文件列
|
||
// if config.AddSourceColumn {
|
||
// cellName, _ := excelize.CoordinatesToCellName(1+colOffset, currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, filepath.Base(result.filename))
|
||
// colOffset++
|
||
// }
|
||
//
|
||
// // 写入原始数据
|
||
// for colIndex, cell := range row {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1+colOffset, currentRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, cell)
|
||
// }
|
||
//
|
||
// currentRow++
|
||
// rowsMerged++
|
||
// totalRowsMerged++
|
||
// }
|
||
//
|
||
// //// 添加分隔行
|
||
// //if rowsMerged > 0 {
|
||
// // separatorCell, _ := excelize.CoordinatesToCellName(1, currentRow)
|
||
// // outputFile.SetCellValue(config.SheetName, separatorCell,
|
||
// // fmt.Sprintf("=== 文件 %d/%d: %s ===",
|
||
// // result.index+1, len(results), filepath.Base(result.filename)))
|
||
// // currentRow++
|
||
// //}
|
||
// }
|
||
//
|
||
// // 保存输出文件
|
||
// if err := outputFile.SaveAs(config.OutputFile); err != nil {
|
||
// return fmt.Errorf("保存合并文件失败: %v", err)
|
||
// }
|
||
//
|
||
// fmt.Printf("并行合并完成!结果保存在: %s\n", config.OutputFile)
|
||
// fmt.Printf("统计信息:\n")
|
||
// fmt.Printf(" - 合并文件数: %d\n", len(results))
|
||
// fmt.Printf(" - 合并数据行数: %d\n", totalRowsMerged)
|
||
//
|
||
// return em.verifyMergeResult(config.OutputFile, config.SheetName)
|
||
//}
|
||
//
|
||
//// MergeByColumn 按列合并Excel文件
|
||
//func (em *ExcelManager) MergeByColumn(config MergeConfig) error {
|
||
// em.mu.Lock()
|
||
// defer em.mu.Unlock()
|
||
//
|
||
// // 获取要合并的文件列表
|
||
// filesToMerge, err := em.getFilesToMerge(config)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
//
|
||
// fmt.Printf("开始按列合并 %d 个文件:\n", len(filesToMerge))
|
||
//
|
||
// // 创建新的输出文件
|
||
// outputFile := excelize.NewFile()
|
||
// defer outputFile.Close()
|
||
//
|
||
// // 删除默认的Sheet1
|
||
// outputFile.DeleteSheet("Sheet1")
|
||
//
|
||
// // 创建目标sheet
|
||
// sheetIndex, err := outputFile.NewSheet(config.SheetName)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建sheet失败: %v", err)
|
||
// }
|
||
// outputFile.SetActiveSheet(sheetIndex)
|
||
//
|
||
// currentCol := 1
|
||
//
|
||
// // 合并所有文件
|
||
// for fileIndex, sourceFile := range filesToMerge {
|
||
// fmt.Printf("[%d/%d] 正在处理文件: %s\n", fileIndex+1, len(filesToMerge), filepath.Base(sourceFile))
|
||
//
|
||
// // 打开源文件
|
||
// srcFile, err := excelize.OpenFile(sourceFile)
|
||
// if err != nil {
|
||
// return fmt.Errorf("打开文件 %s 失败: %v", sourceFile, err)
|
||
// }
|
||
// defer srcFile.Close()
|
||
//
|
||
// // 确定要读取的sheet
|
||
// sourceSheet := em.getSourceSheet(srcFile, config.SourceSheet)
|
||
// if sourceSheet == "" {
|
||
// return fmt.Errorf("未找到可用的sheet")
|
||
// }
|
||
//
|
||
// // 读取源文件数据
|
||
// rows, err := srcFile.GetRows(sourceSheet)
|
||
// if err != nil {
|
||
// return fmt.Errorf("读取文件 %s 失败: %v,跳过\n", sourceFile, err)
|
||
// }
|
||
//
|
||
// if len(rows) == 0 {
|
||
// fmt.Printf("警告: 文件 %s 的sheet '%s' 没有数据,跳过\n", sourceFile, sourceSheet)
|
||
// continue
|
||
// }
|
||
//
|
||
// // 按列写入数据
|
||
// for rowIndex, row := range rows {
|
||
// // 写入当前列的所有行
|
||
// for colIndex, cell := range row {
|
||
// targetRow := rowIndex + 1
|
||
// cellName, _ := excelize.CoordinatesToCellName(currentCol+colIndex, targetRow)
|
||
// outputFile.SetCellValue(config.SheetName, cellName, cell)
|
||
// }
|
||
// }
|
||
//
|
||
// // 添加文件名称到第一行(作为列标题)
|
||
// titleCell, _ := excelize.CoordinatesToCellName(currentCol, 1)
|
||
// outputFile.SetCellValue(config.SheetName, titleCell, filepath.Base(sourceFile))
|
||
//
|
||
// // 移动到下一组列
|
||
// if len(rows) > 0 && len(rows[0]) > 0 {
|
||
// currentCol += len(rows[0])
|
||
// } else {
|
||
// currentCol += 1
|
||
// }
|
||
// }
|
||
//
|
||
// // 保存输出文件
|
||
// if err := outputFile.SaveAs(config.OutputFile); err != nil {
|
||
// return fmt.Errorf("保存合并文件失败: %v", err)
|
||
// }
|
||
//
|
||
// fmt.Printf("按列合并完成!结果保存在: %s\n", config.OutputFile)
|
||
// return nil
|
||
//}
|
||
//
|
||
//// MergeSheetsInSameFile 合并同一文件中的多个sheet
|
||
//func (em *ExcelManager) MergeSheetsInSameFile(filename, outputFile string, targetSheetName string) error {
|
||
// em.mu.RLock()
|
||
// defer em.mu.RUnlock()
|
||
//
|
||
// file, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// defer file.Close()
|
||
//
|
||
// // 获取所有sheet
|
||
// sheets := file.GetSheetList()
|
||
// if len(sheets) == 0 {
|
||
// return fmt.Errorf("文件 %s 中没有sheet", filename)
|
||
// }
|
||
//
|
||
// // 创建新的输出文件
|
||
// output := excelize.NewFile()
|
||
// defer output.Close()
|
||
//
|
||
// // 删除默认的Sheet1
|
||
// output.DeleteSheet("Sheet1")
|
||
//
|
||
// // 创建目标sheet
|
||
// sheetIndex, err := output.NewSheet(targetSheetName)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建sheet失败: %v", err)
|
||
// }
|
||
// output.SetActiveSheet(sheetIndex)
|
||
//
|
||
// currentRow := 1
|
||
//
|
||
// for _, sheet := range sheets {
|
||
// // 读取sheet数据
|
||
// rows, err := file.GetRows(sheet)
|
||
// if err != nil {
|
||
// fmt.Printf("警告: 读取sheet %s 失败: %v,跳过\n", sheet, err)
|
||
// continue
|
||
// }
|
||
//
|
||
// if len(rows) == 0 {
|
||
// continue
|
||
// }
|
||
//
|
||
// // 添加sheet名称作为标题
|
||
// titleCell, _ := excelize.CoordinatesToCellName(1, currentRow)
|
||
// output.SetCellValue(targetSheetName, titleCell, fmt.Sprintf("=== Sheet: %s ===", sheet))
|
||
// currentRow++
|
||
//
|
||
// // 写入sheet数据
|
||
// for _, row := range rows {
|
||
// for colIndex, cell := range row {
|
||
// cellName, _ := excelize.CoordinatesToCellName(colIndex+1, currentRow)
|
||
// output.SetCellValue(targetSheetName, cellName, cell)
|
||
// }
|
||
// currentRow++
|
||
// }
|
||
//
|
||
// // 添加空行分隔
|
||
// currentRow++
|
||
// }
|
||
//
|
||
// // 保存输出文件
|
||
// return output.SaveAs(outputFile)
|
||
//}
|
||
//
|
||
//// ============ 辅助结构和方法 ============
|
||
//
|
||
//// 文件任务结构
|
||
//type fileTask struct {
|
||
// filename string
|
||
// index int
|
||
// total int
|
||
//}
|
||
//
|
||
//// 文件结果结构
|
||
//type fileResult struct {
|
||
// filename string
|
||
// index int
|
||
// data fileData
|
||
//}
|
||
//
|
||
//// 文件数据结构
|
||
//type fileData struct {
|
||
// rows [][]string
|
||
// err error
|
||
//}
|
||
//
|
||
//// 并行读取Excel文件
|
||
//func (em *ExcelManager) readExcelFileParallel(filename, sheetName string) fileData {
|
||
// srcFile, err := excelize.OpenFile(filename)
|
||
// if err != nil {
|
||
// return fileData{err: err}
|
||
// }
|
||
// defer srcFile.Close()
|
||
//
|
||
// sourceSheet := em.getSourceSheet(srcFile, sheetName)
|
||
// if sourceSheet == "" {
|
||
// return fileData{err: fmt.Errorf("未找到可用的sheet")}
|
||
// }
|
||
//
|
||
// rows, err := srcFile.GetRows(sourceSheet)
|
||
// return fileData{
|
||
// rows: rows,
|
||
// err: err,
|
||
// }
|
||
//}
|
||
//
|
||
//// 检查行是否为空
|
||
//func (em *ExcelManager) isRowEmpty(row []string) bool {
|
||
// for _, cell := range row {
|
||
// if strings.TrimSpace(cell) != "" {
|
||
// return false
|
||
// }
|
||
// }
|
||
// return true
|
||
//}
|
||
//
|
||
//// 清理测试文件
|
||
//func cleanupFiles(file string) {
|
||
// if _, err := os.Stat(file); err == nil {
|
||
// os.Remove(file)
|
||
// fmt.Printf("删除: %s\n", file)
|
||
// }
|
||
//}
|
||
//
|
||
//// 辅助函数:将数据转换为JSON字符串
|
||
//func convertToJSON(data interface{}) string {
|
||
// // 这里使用简单的转换,实际可以使用 encoding/json 包
|
||
// switch v := data.(type) {
|
||
// case [][]string:
|
||
// var result []string
|
||
// for _, row := range v {
|
||
// result = append(result, strings.Join(row, ","))
|
||
// }
|
||
// return strings.Join(result, "\n")
|
||
// case []string:
|
||
// return strings.Join(v, "\n")
|
||
// default:
|
||
// return fmt.Sprintf("%v", data)
|
||
// }
|
||
//}
|
||
//
|
||
//// 将C字符串数组转换为Go字符串切片
|
||
//func cStringArrayToStringSlice(cArray **C.char, length int) []string {
|
||
// if cArray == nil || length == 0 {
|
||
// return nil
|
||
// }
|
||
//
|
||
// var goStrs []string
|
||
// for i := 0; i < length; i++ {
|
||
// ptr := (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(uintptr(0))))
|
||
// if *ptr != nil {
|
||
// goStrs = append(goStrs, C.GoString(*ptr))
|
||
// }
|
||
// }
|
||
//
|
||
// return goStrs
|
||
//}
|
||
//
|
||
//// 辅助函数:设置错误信息
|
||
//func setError(err string) {
|
||
// // 这里可以添加日志记录等操作
|
||
// fmt.Printf("Excel操作错误: %s\n", err)
|
||
//}
|
||
//
|
||
//func ParseExcelDataToJSON(excelData string) ([]map[string]string, error) {
|
||
// if excelData == "" {
|
||
// return nil, fmt.Errorf("Excel数据为空")
|
||
// }
|
||
//
|
||
// // 使用csv解析器解析数据
|
||
// reader := csv.NewReader(strings.NewReader(excelData))
|
||
// records, err := reader.ReadAll()
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("解析CSV数据失败: %v", err)
|
||
// }
|
||
//
|
||
// if len(records) < 2 {
|
||
// return nil, fmt.Errorf("数据行数不足")
|
||
// }
|
||
//
|
||
// // 提取表头(第一行)
|
||
// headers := records[0]
|
||
//
|
||
// // 将数据转换为JSON格式
|
||
// var jsonData []map[string]string
|
||
//
|
||
// // 从第二行开始(跳过表头)
|
||
// for i := 1; i < len(records); i++ {
|
||
// row := records[i]
|
||
// rowData := make(map[string]string)
|
||
//
|
||
// // 确保每行的列数与表头一致
|
||
// for j := 0; j < len(headers) && j < len(row); j++ {
|
||
// rowData[headers[j]] = row[j]
|
||
// }
|
||
// jsonData = append(jsonData, rowData)
|
||
// }
|
||
//
|
||
// return jsonData, nil
|
||
//}
|
||
//
|
||
//// ============ CGO 导出函数 ============
|
||
//
|
||
//var (
|
||
// managerStore sync.Map
|
||
// nextHandle int64 = 1
|
||
// handleMutex sync.Mutex // 添加互斥锁保证线程安全
|
||
//)
|
||
//
|
||
//// 创建新的Excel管理器并返回指针
|
||
////
|
||
////export NewExcelManagerInstance
|
||
//func NewExcelManagerInstance() C.longlong {
|
||
// manager := NewExcelManager()
|
||
//
|
||
// handleMutex.Lock()
|
||
// handle := nextHandle
|
||
// nextHandle++
|
||
// handleMutex.Unlock()
|
||
//
|
||
// // 将Go对象存储在map中
|
||
// managerStore.Store(handle, manager)
|
||
//
|
||
// return C.longlong(handle)
|
||
//}
|
||
//
|
||
//// 释放Excel管理器
|
||
////
|
||
////export FreeExcelManager
|
||
//func FreeExcelManager(handle C.longlong) {
|
||
// h := int64(handle)
|
||
//
|
||
// // 从map中删除并清理
|
||
// if mgr, ok := managerStore.Load(h); ok {
|
||
// if manager, ok := mgr.(*ExcelManager); ok {
|
||
// manager.CloseAll()
|
||
// }
|
||
// managerStore.Delete(h)
|
||
// }
|
||
//}
|
||
//
|
||
//// 读取Excel数据
|
||
////
|
||
////export ReadExcelData
|
||
//func ReadExcelData(handle C.longlong, filename *C.char, sheet *C.char, result **C.char) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// data, err := manager.ReadData(goFilename, goSheet)
|
||
// if err != nil {
|
||
// return C.int(-1)
|
||
// }
|
||
// // 将数据转换为JSON字符串
|
||
// jsonStr := convertToJSON(data)
|
||
//
|
||
// // 将结果转换为JSON格式
|
||
// jsonData, err := ParseExcelDataToJSON(jsonStr)
|
||
// var datas string
|
||
// if err != nil {
|
||
// fmt.Printf("转换JSON失败: %v\n", err)
|
||
// } else {
|
||
// // 将JSON数据格式化输出
|
||
// jsonBytes, err := json.MarshalIndent(jsonData, "", " ")
|
||
// if err != nil {
|
||
// fmt.Printf("格式化JSON失败: %v\n", err)
|
||
// } else {
|
||
// datas = string(jsonBytes)
|
||
// }
|
||
// }
|
||
//
|
||
// *result = C.CString(datas)
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 批量写入数据到Excel文件
|
||
////
|
||
////export WriteBatchData
|
||
//func WriteBatchData(handle C.longlong, filename *C.char, sheet *C.char, cells *C.char, values *C.char, count C.int) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// goCells := C.GoString(cells)
|
||
// goValues := C.GoString(values)
|
||
//
|
||
// var cell []string
|
||
// var value []string
|
||
// err := json.Unmarshal([]byte(goCells), &cell)
|
||
// if err != nil {
|
||
// setError(fmt.Sprintf("解析数据失败: %v,数据: %s", err, goCells))
|
||
// return C.int(-1)
|
||
// }
|
||
// err = json.Unmarshal([]byte(goValues), &value)
|
||
// if err != nil {
|
||
// setError(fmt.Sprintf("解析数据失败: %v,数据: %s", err, goValues))
|
||
// return C.int(-1)
|
||
// }
|
||
// // 构建数据映射
|
||
// data := make(map[string]interface{})
|
||
// for i, c := range cell {
|
||
// data[c] = value[i]
|
||
// }
|
||
// err = manager.WriteData(goFilename, goSheet, data)
|
||
// if err != nil {
|
||
// fmt.Printf("批量写入数据失败: %v\n", err)
|
||
// return C.int(-1)
|
||
// }
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 追加数据到Excel文件末尾
|
||
////
|
||
////export AppendDataToExcel
|
||
//func AppendDataToExcel(handle C.longlong, filename *C.char, sheet *C.char, values *C.char, count C.int) C.int {
|
||
// h := int64(handle)
|
||
//
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// goValues := C.GoString(values)
|
||
// var value []string
|
||
// err := json.Unmarshal([]byte(goValues), &value)
|
||
// if err != nil {
|
||
// setError(fmt.Sprintf("解析数据失败: %v,数据: %s", err, goValues))
|
||
// return C.int(-1)
|
||
// }
|
||
// // 转换为interface{}切片
|
||
// var rowData []interface{}
|
||
// for _, val := range value {
|
||
// rowData = append(rowData, val)
|
||
// }
|
||
// err = manager.AppendData(goFilename, goSheet, rowData)
|
||
// if err != nil {
|
||
// fmt.Printf("追加数据失败: %v\n", err)
|
||
// return C.int(-1)
|
||
// }
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 搜索包含关键字的单元格
|
||
////
|
||
////export SearchByKeyword
|
||
//func SearchByKeyword(handle C.longlong, filename *C.char, sheet *C.char, keyword *C.char, result **C.char) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// goKeyword := C.GoString(keyword)
|
||
// results, err := manager.SearchByKeyword(goFilename, goSheet, goKeyword)
|
||
// if err != nil {
|
||
// return C.int(-1)
|
||
// }
|
||
// // 将结果转换为JSON字符串
|
||
// jsonStr := convertToJSON(results)
|
||
// *result = C.CString(jsonStr)
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 搜索整行包含关键字的行
|
||
////
|
||
////export SearchRowsByKeyword
|
||
//func SearchRowsByKeyword(handle C.longlong,
|
||
// filename *C.char,
|
||
// sheet *C.char,
|
||
// keyword *C.char,
|
||
// result **C.char) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// goKeyword := C.GoString(keyword)
|
||
// results, err := manager.SearchRowData(goFilename, goSheet, goKeyword)
|
||
// if err != nil {
|
||
// return C.int(-1)
|
||
// }
|
||
// // 将结果转换为JSON字符串
|
||
// jsonStr := convertToJSON(results)
|
||
// *result = C.CString(jsonStr)
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 创建新文件并写入数据
|
||
////
|
||
////export CreateAndWriteExcel
|
||
//func CreateAndWriteExcel(handle C.longlong, filename *C.char, sheet *C.char, rowsData *C.char) C.int {
|
||
// h := int64(handle)
|
||
//
|
||
// // 获取管理器
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// setError("Invalid handle")
|
||
// return C.int(-1)
|
||
// }
|
||
//
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// setError("Invalid manager type")
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goSheet := C.GoString(sheet)
|
||
// goRowsData := C.GoString(rowsData)
|
||
// var data [][]string
|
||
// err2 := json.Unmarshal([]byte(goRowsData), &data)
|
||
// if err2 != nil {
|
||
// // 更详细的错误信息
|
||
// setError(fmt.Sprintf("解析数据失败: %v, 数据: %s", err2, goRowsData))
|
||
// return C.int(-1)
|
||
// }
|
||
// // 调用管理器方法
|
||
// err := manager.CreateAndWrite(goFilename, goSheet, data)
|
||
// if err != nil {
|
||
// setError(fmt.Sprintf("创建并写入文件失败: %v", err))
|
||
// return C.int(-1)
|
||
// }
|
||
// fmt.Printf("文件创建成功: %s\n", goFilename)
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 增强版合并Excel文件(支持指定文件列表)
|
||
////
|
||
////export MergeExcelFilesEx
|
||
//func MergeExcelFilesEx(handle C.longlong,
|
||
// sourceDir *C.char,
|
||
// specificFiles *C.char,
|
||
// outputFile *C.char,
|
||
// sheetName *C.char,
|
||
// mergeByColumn C.int,
|
||
// includeHeaders C.int,
|
||
// skipEmptyRows C.int,
|
||
// filePattern *C.char,
|
||
// sourceSheet *C.char,
|
||
// addSourceColumn C.int,
|
||
// addIndexColumn C.int) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
//
|
||
// goSpecificFiles := C.GoString(specificFiles)
|
||
// var data []string
|
||
// err2 := json.Unmarshal([]byte(goSpecificFiles), &data)
|
||
// if err2 != nil {
|
||
// // 更详细的错误信息
|
||
// setError(fmt.Sprintf("解析数据失败: %v, 数据: %s", err2, goSpecificFiles))
|
||
// return C.int(-1)
|
||
// }
|
||
// // 构建配置
|
||
// config := MergeConfig{
|
||
// SourceDir: C.GoString(sourceDir),
|
||
// SpecificFiles: data,
|
||
// OutputFile: C.GoString(outputFile),
|
||
// SheetName: C.GoString(sheetName),
|
||
// MergeByColumn: mergeByColumn != 0,
|
||
// IncludeHeaders: includeHeaders != 0,
|
||
// SkipEmptyRows: skipEmptyRows != 0,
|
||
// FilePattern: C.GoString(filePattern),
|
||
// AddSourceColumn: addSourceColumn != 0,
|
||
// AddIndexColumn: addIndexColumn != 0,
|
||
// SourceSheet: C.GoString(sourceSheet),
|
||
// }
|
||
// // 根据合并模式调用不同的方法
|
||
// var err error
|
||
// if config.MergeByColumn {
|
||
// err = manager.MergeByColumn(config)
|
||
// } else {
|
||
// err = manager.MergeExcelFiles(config)
|
||
// }
|
||
// if err != nil {
|
||
// fmt.Printf("合并Excel文件失败: %v\n", err)
|
||
// return C.int(-1)
|
||
// }
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 并行合并Excel文件(增强版)
|
||
////
|
||
////export MergeExcelFilesParallelEx
|
||
//func MergeExcelFilesParallelEx(handle C.longlong,
|
||
// sourceDir *C.char,
|
||
// specificFiles **C.char,
|
||
// fileCount C.int,
|
||
// outputFile *C.char,
|
||
// sheetName *C.char,
|
||
// includeHeaders C.int,
|
||
// skipEmptyRows C.int,
|
||
// filePattern *C.char,
|
||
// sourceSheet *C.char,
|
||
// addSourceColumn C.int,
|
||
// addIndexColumn C.int,
|
||
// workers C.int) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// // 构建配置
|
||
// config := MergeConfig{
|
||
// SourceDir: C.GoString(sourceDir),
|
||
// OutputFile: C.GoString(outputFile),
|
||
// SheetName: C.GoString(sheetName),
|
||
// IncludeHeaders: includeHeaders != 0,
|
||
// SkipEmptyRows: skipEmptyRows != 0,
|
||
// FilePattern: C.GoString(filePattern),
|
||
// AddSourceColumn: addSourceColumn != 0,
|
||
// AddIndexColumn: addIndexColumn != 0,
|
||
// SourceSheet: C.GoString(sourceSheet),
|
||
// }
|
||
//
|
||
// // 如果有指定的文件列表,则添加到配置中
|
||
// if fileCount > 0 && specificFiles != nil {
|
||
// config.SpecificFiles = cStringArrayToStringSlice(specificFiles, int(fileCount))
|
||
// }
|
||
//
|
||
// err := manager.MergeExcelFilesParallel(config, int(workers))
|
||
// if err != nil {
|
||
// fmt.Printf("并行合并Excel文件失败: %v\n", err)
|
||
// return C.int(-1)
|
||
// }
|
||
//
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 合并同一文件中的多个sheet
|
||
////
|
||
////export MergeSheetsInFile
|
||
//func MergeSheetsInFile(handle C.longlong,
|
||
// filename *C.char,
|
||
// outputFile *C.char,
|
||
// targetSheetName *C.char) C.int {
|
||
// h := int64(handle)
|
||
// mgr, ok := managerStore.Load(h)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// manager, ok := mgr.(*ExcelManager)
|
||
// if !ok {
|
||
// return C.int(-1)
|
||
// }
|
||
// goFilename := C.GoString(filename)
|
||
// goOutputFile := C.GoString(outputFile)
|
||
// goTargetSheet := C.GoString(targetSheetName)
|
||
//
|
||
// err := manager.MergeSheetsInSameFile(goFilename, goOutputFile, goTargetSheet)
|
||
// if err != nil {
|
||
// fmt.Printf("合并sheet失败: %v\n", err)
|
||
// return C.int(-1)
|
||
// }
|
||
//
|
||
// return C.int(0)
|
||
//}
|
||
//
|
||
//// 释放C字符串
|
||
////
|
||
////export FreeCString
|
||
//func FreeCString(str *C.char) {
|
||
// if str != nil {
|
||
// C.free(unsafe.Pointer(str))
|
||
// }
|
||
//}
|
||
//
|
||
////func main() {
|
||
////
|
||
////}
|