diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..58a1424 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/ExcelHelper/bin/Debug/net9.0-windows/ExcelHelper.dll", + "args": [], + "cwd": "${workspaceFolder}/src/ExcelHelper", + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..e0cd9b2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/src/ExcelHelper/ExcelHelper.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/src/ExcelHelper/ExcelHelper.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/src/ExcelHelper/ExcelHelper.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/src/ExcelHelper/Utils/Excel2Prompt.cs b/src/ExcelHelper/Utils/Excel2Prompt.cs index bb2512d..83dec01 100644 --- a/src/ExcelHelper/Utils/Excel2Prompt.cs +++ b/src/ExcelHelper/Utils/Excel2Prompt.cs @@ -14,7 +14,7 @@ public class Excel2Prompt /// /// A /// - public static string ConverterToPrompt(IEnumerable excelData, IEnumerable columns, string startCell) + public static string ConverterToPrompt(IEnumerable excelData, Dictionary columns, string startCell) { /* 示例: @@ -46,13 +46,15 @@ public class Excel2Prompt int columnIndex = startColumnIndex; foreach (var column in columns) { + var colOriName = column.Key; + var safeColName = column.Value; columnIndex++; string columnLetter = GetExcelColumnName(columnIndex); var columnData = dataList.Select(row => { var rowDict = (IDictionary)row; - return rowDict.ContainsKey(column) ? rowDict[column] : null; + return rowDict.ContainsKey(safeColName) ? rowDict[safeColName] : null; }).ToList(); var nonNullData = columnData.Where(value => value != null).ToList(); @@ -63,7 +65,7 @@ public class Excel2Prompt // 自动识别数据类型 var dataType = GetColumnDataType(nonNullData); - var prompt = $"- Column '{column.Replace("\n", " ")}' (Excel Column {columnLetter})" + + var prompt = $"- Column '{column.Key.Replace("\n", " ")}' (Excel Column {columnLetter})" + $" - Type: {dataType}" + $" - Sample values: ['{string.Join("', '", sampleValues)}']"; prompts.Add(prompt); diff --git a/src/ExcelHelper/Views/Components/AiMessageControll.xaml.cs b/src/ExcelHelper/Views/Components/AiMessageControll.xaml.cs index da03aa6..30bfee0 100644 --- a/src/ExcelHelper/Views/Components/AiMessageControll.xaml.cs +++ b/src/ExcelHelper/Views/Components/AiMessageControll.xaml.cs @@ -80,24 +80,27 @@ public partial class AiMessageControll : UserControl private void SendButton_Click(object sender, RoutedEventArgs e) { - if (SendCommand != null && SendCommand.CanExecute(CurrentMessage)) - { - SendCommand.Execute(CurrentMessage); - } + InvokeSendCommand(); } private void MessageInput_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter && !string.IsNullOrEmpty(CurrentMessage) && !IsWaiting) { - if (SendCommand != null && SendCommand.CanExecute(CurrentMessage)) - { - SendCommand.Execute(CurrentMessage); - } + InvokeSendCommand(); e.Handled = true; } } - + + private void InvokeSendCommand() + { + if (SendCommand != null && SendCommand.CanExecute(CurrentMessage)) + { + SendCommand.Execute(CurrentMessage); + CurrentMessage = ""; + } + } + public void ScrollToEnd() { if (Messages.Count > 0) diff --git a/src/ExcelHelper/Views/ViewModels/ImportViewModel.cs b/src/ExcelHelper/Views/ViewModels/ImportViewModel.cs index 3f9f567..cdcd307 100644 --- a/src/ExcelHelper/Views/ViewModels/ImportViewModel.cs +++ b/src/ExcelHelper/Views/ViewModels/ImportViewModel.cs @@ -15,13 +15,75 @@ using ExcelHelper.Views.Components; using MiniExcelLibs; using MiniExcelLibs.OpenXml; using SqlSugar; +using System.Text.RegularExpressions; +using System.Dynamic; +using System.Diagnostics; namespace ExcelHelper.Views.ViewModels; public partial class ImportViewModel : ObservableRecipient, IViewModel { - + // 新增列名映射字典 + private readonly Dictionary _columnMappings = new(); + + private void GenColumns(IEnumerable columns) + { + ExcelColumns.Clear(); + TableColumns.Clear(); + _columnMappings.Clear(); + + if (UseHeaderRow) + { + foreach (var columnName in columns) + { + // 修改正则表达式,保留中文字符(\u4e00-\u9fff) + var safeColumnName = Regex.Replace(columnName, @"[^a-zA-Z0-9\u4e00-\u9fff]", "_") + .Trim('_') + .ReplaceMultiple("__", "_"); + _columnMappings[columnName] = safeColumnName; // 保存映射关系 + + var column = new DataGridTextColumn + { + Header = columnName, + Binding = new System.Windows.Data.Binding($"{safeColumnName}"), // 恢复方括号语法 + Width = DataGridLength.Auto + }; + ExcelColumns.Add(column); + } + } + else + { + for (var i = 'A'; i < 'Z'; i++) + { + var column = new DataGridTextColumn + { + Header = $"{i}", + Binding = new System.Windows.Data.Binding($"{i}"), + Width = DataGridLength.Auto + }; + ExcelColumns.Add(column); + } + } + var columnsSeq = 0; + foreach (var item in ExcelColumns) + { + TableColumns.Add(new TableColumnModel + { + ExcelColumnName = item.Header.ToString(), + TableColumnName = $"Column{columnsSeq}", + }); + columnsSeq++; + } + if (ExcelColumns.Count > 0) + { + WeakReferenceMessenger.Default.Send(new UpdateDataGridColumnsMessage([.. ExcelColumns])); + } + else + { + WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("未读取到列信息!")); + } + } private readonly AiHelper AiHelper = new("deepseek-r1-250120", false); public Task FileDrop(string[] files) @@ -67,15 +129,7 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel IsLoading = false; return; } - var excelData = await GetExcelData(path, config); - if (MaxRow != 0) - { - ExcelData = excelData.Take(Math.Min(MaxRow, 300)); - } - else - { - ExcelData = excelData.Take(300); - } + var currentSheetName = SelectedSheetName; var columns = MiniExcel.GetColumns(path, useHeaderRow: UseHeaderRow, startCell: StartCell, sheetName: currentSheetName, configuration: config); @@ -90,9 +144,42 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel { SelectedSheetName = Sheets.FirstOrDefault(it => it.Equals(currentSheetName)); } + + var excelData = await GetExcelData(path, config); + // 新增数据处理逻辑 + if (UseHeaderRow) + { + var processedData = new List(); + foreach (var row in excelData) + { + var newRow = new ExpandoObject(); + var newRowDict = (IDictionary)newRow; + var originalRow = (IDictionary)row; + foreach (var col in columns) + { + if (_columnMappings.TryGetValue(col, out var safeName) + && originalRow.TryGetValue(col, out var value)) + { + newRowDict[safeName] = value; + Debug.WriteLine($"Mapping {col} to {safeName}"); + } + } + processedData.Add(newRow); + } + excelData = processedData; + } + if (MaxRow != 0) + { + ExcelData = excelData.Take(Math.Min(MaxRow, 300)); + } + else + { + ExcelData = excelData.Take(300); + } + MaxRow = ExcelData.Count(); - ExcelPromptString = Excel2Prompt.ConverterToPrompt(ExcelData, columns,StartCell); + ExcelPromptString = Excel2Prompt.ConverterToPrompt(ExcelData, _columnMappings, StartCell); } catch (Exception ex) { @@ -108,57 +195,6 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel : MiniExcel.QueryRange(path, sheetName: SelectedSheetName, useHeaderRow: UseHeaderRow, startCell: StartCell, endCell: EndCell, configuration: config); } - - private void GenColumns(IEnumerable columns) - { - ExcelColumns.Clear(); - TableColumns.Clear(); - if (UseHeaderRow) - { - foreach (var columnName in columns) - { - var column = new DataGridTextColumn - { - Header = columnName, - Binding = new System.Windows.Data.Binding($"{columnName}"), - Width = DataGridLength.Auto - }; - ExcelColumns.Add(column); - } - } - else - { - for (var i = 'A'; i < 'Z'; i++) - { - var column = new DataGridTextColumn - { - Header = $"{i}", - Binding = new System.Windows.Data.Binding($"{i}"), - Width = DataGridLength.Auto - }; - ExcelColumns.Add(column); - } - } - var columnsSeq = 0; - foreach (var item in ExcelColumns) - { - TableColumns.Add(new TableColumnModel - { - ExcelColumnName = item.Header.ToString(), - TableColumnName = $"Column{columnsSeq}", - }); - columnsSeq++; - } - if (ExcelColumns.Count > 0) - { - WeakReferenceMessenger.Default.Send(new UpdateDataGridColumnsMessage([.. ExcelColumns])); - } - else - { - WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("未读取到列信息!")); - } - } - [RelayCommand] private void OnReLoadExcel() { @@ -431,3 +467,14 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel private string _excelPromptString; #endregion } + +// 将扩展方法移到类外部 +public static class StringExtensions +{ + public static string ReplaceMultiple(this string input, string oldValue, string newValue) + { + while (input.Contains(oldValue)) + input = input.Replace(oldValue, newValue); + return input; + } +}