using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Controls; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using ExcelHelper.Message; using ExcelHelper.Model; using ExcelHelper.Utils; using MiniExcelLibs; using MiniExcelLibs.OpenXml; using SqlSugar; namespace ExcelHelper.Views.ViewModels; public partial class ImportViewModel : ObservableRecipient, IViewModel { public Task FileDrop(string[] files) { IsLoading = true; ExcelFiles.Clear(); SelectedSheetName = null; Sheets.Clear(); MaxRow = 0; foreach (var item in files) { if(!item.EndsWith(".xlsx") && !item.EndsWith(".xls")) { WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("请拖入Excel文件!")); IsLoading = false; return Task.CompletedTask; } ExcelFiles.Add(item); } //ReadForExcel(ExcelFiles.First()); CurrentFilePath = ExcelFiles.FirstOrDefault(); IsLoading = false; return Task.CompletedTask; } public async void ReadForExcel(string path, bool isReload = false) { IsLoading = true; //await Task.Factory.StartNew(async () => //{ try { var config = new OpenXmlConfiguration() { FillMergedCells = FillMergedCells }; if (string.IsNullOrEmpty(path)) { 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); GenColumns(columns); GetSheets(path); if (string.IsNullOrEmpty(currentSheetName)) { SelectedSheetName = Sheets.FirstOrDefault(); } else { SelectedSheetName = Sheets.FirstOrDefault(it => it.Equals(currentSheetName)); } MaxRow = ExcelData.Count(); PromptString = Excel2Prompt.ConverterToPrompt(ExcelData, columns); } catch (Exception ex) { WeakReferenceMessenger.Default.Send(new ErrorDialogMessage($"出现了异常!{ex}")); } IsLoading = false; } public async Task> GetExcelData(string path, Configuration config) { return string.IsNullOrEmpty(EndCell) ? await MiniExcel.QueryAsync(path, sheetName: SelectedSheetName, useHeaderRow: UseHeaderRow, startCell: StartCell, configuration: config) : 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); } } int 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() { ReadForExcel(CurrentFilePath, isReload: true); } [RelayCommand] private void OnReadSheets() { if (!string.IsNullOrWhiteSpace(CurrentFilePath)) { GetSheets(CurrentFilePath); SelectedSheetName = Sheets.FirstOrDefault(); } } private void GetSheets(string excelPath) { var sheets = MiniExcel.GetSheetNames(excelPath); if (Sheets == null) { Sheets = []; } else { Sheets.Clear(); } sheets.ForEach(sheetName => { Sheets.Add(sheetName); }); } [RelayCommand] private void OnTestDbConn() { try { var client = GetClient(); var tables = client.Ado.ExecuteCommand("select 1"); WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("连接成功!")); } catch (Exception ex) { WeakReferenceMessenger.Default.Send(new ErrorDialogMessage($"连接失败!{ex}")); } } private SqlSugarClient GetClient() { var connStr = GetConnStr(DbType); if (string.IsNullOrEmpty(connStr)) { WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("未知的数据库类型!")); return null; } try { var client = new SqlSugarClient(new ConnectionConfig { ConnectionString = connStr, DbType = DbType switch { //"MySql" => SqlSugar.DbType.MySql, "Sqlite" => SqlSugar.DbType.Sqlite, "SqlServer" => SqlSugar.DbType.SqlServer, _ => throw new Exception("未知的数据库类型") }, IsAutoCloseConnection = true }); return client; //WeakReferenceMessenger.Default.Send(new ErrorDialogMessage("连接成功!")); } catch (Exception ex) { WeakReferenceMessenger.Default.Send(new ErrorDialogMessage($"连接失败!{ex}")); return null; } } private string GetConnStr(string dbType) { var encryptStr = ""; if (IsEncrypt) { encryptStr = "Encrypt=True;TrustServerCertificate=True;"; } return dbType switch { //"MySql" => $"Server={DbServer};Port={DbPort};Database={DbName};User Id={DbUser};Password={DbPassword};{encryptStr}", "SqlServer" => $"Server={DbServer},{DbPort};Database={DbName};User Id={DbUser};Password={DbPassword};{encryptStr}", //"PostgreSql" => $"Server={DbServer};Port={DbPort};Database={DbName};User Id={DbUser};Password={DbPassword};{encryptStr}", "Sqlite" => $"DataSource={DbServer};", _ => "" }; } #region Props [ObservableProperty] private IEnumerable _excelData; [ObservableProperty] private ObservableCollection _excelFiles = []; [ObservableProperty] private ObservableCollection _excelColumns = []; [ObservableProperty] private ObservableCollection _tableColumns = []; /// /// 是否正在加载 /// [ObservableProperty] private bool _isLoading = false; /// /// 使用首行作为表头 /// [ObservableProperty] private bool _useHeaderRow = false; /// /// 选中的Sheet /// [ObservableProperty] private string _selectedSheetName; /// /// Sheets列表 /// [ObservableProperty] private ObservableCollection _sheets = []; /// /// 起始位置 /// [ObservableProperty] private string _startCell = "A1"; /// /// 结束位置 /// [ObservableProperty] private string _endCell; /// /// 使用首行作为表头 /// [ObservableProperty] private bool _fillMergedCells = false; /// /// 最大行数 /// [ObservableProperty] private int _maxRow = 0; /// /// 当前文件路径 /// private string _currentFilePath; public string CurrentFilePath { get => _currentFilePath; set { SetProperty(ref _currentFilePath, value); ReadForExcel(value); } } /// /// Excel文件密码 /// [ObservableProperty] private string _excelPassword; [ObservableProperty] private string _dbType; /// /// 加密连接 /// [ObservableProperty] private bool _isEncrypt; [ObservableProperty] private string _dbUser; [ObservableProperty] private string _dbPassword; [ObservableProperty] private string _dbServer; [ObservableProperty] private string _dbPort; [ObservableProperty] private string _dbName; [ObservableProperty] private string _promptString; #endregion }