ExcelHelper/Views/ViewModels/ImportViewModel.cs

360 lines
9.9 KiB
C#

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<IEnumerable<dynamic>> 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<string> 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<dynamic> _excelData;
[ObservableProperty]
private ObservableCollection<string> _excelFiles = [];
[ObservableProperty]
private ObservableCollection<DataGridColumn> _excelColumns = [];
[ObservableProperty]
private ObservableCollection<TableColumnModel> _tableColumns = [];
/// <summary>
/// 是否正在加载
/// </summary>
[ObservableProperty]
private bool _isLoading = false;
/// <summary>
/// 使用首行作为表头
/// </summary>
[ObservableProperty]
private bool _useHeaderRow = false;
/// <summary>
/// 选中的Sheet
/// </summary>
[ObservableProperty]
private string _selectedSheetName;
/// <summary>
/// Sheets列表
/// </summary>
[ObservableProperty]
private ObservableCollection<string> _sheets = [];
/// <summary>
/// 起始位置
/// </summary>
[ObservableProperty]
private string _startCell = "A1";
/// <summary>
/// 结束位置
/// </summary>
[ObservableProperty]
private string _endCell;
/// <summary>
/// 使用首行作为表头
/// </summary>
[ObservableProperty]
private bool _fillMergedCells = false;
/// <summary>
/// 最大行数
/// </summary>
[ObservableProperty]
private int _maxRow = 0;
/// <summary>
/// 当前文件路径
/// </summary>
private string _currentFilePath;
public string CurrentFilePath
{
get => _currentFilePath;
set
{
SetProperty(ref _currentFilePath, value);
ReadForExcel(value);
}
}
/// <summary>
/// Excel文件密码
/// </summary>
[ObservableProperty]
private string _excelPassword;
[ObservableProperty]
private string _dbType;
/// <summary>
/// 加密连接
/// </summary>
[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
}