This commit is contained in:
lihanbo 2024-10-29 16:57:50 +08:00
parent 05b41a5685
commit bad4552f16
14 changed files with 478 additions and 259 deletions

View File

@ -50,8 +50,11 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SQLite" Version="3.13.0" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.171-preview01" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-rc.2.24473.5" />
<PackageReference Include="TinyPinyin" Version="1.1.0" />
</ItemGroup>
</Project>

View File

@ -33,23 +33,29 @@
x:Name="MainFrame"
Grid.Column="1"
NavigationUIVisibility="Hidden" />
<hc:Dialog Background="Transparent" x:Name="MessageDialog" Visibility="Collapsed" Grid.Column="0" Grid.ColumnSpan="2">
<hc:Dialog FontSize="16" Background="Transparent" x:Name="MessageDialog" Visibility="Collapsed" Grid.Column="0" Grid.ColumnSpan="2">
<Border BorderBrush="Gray" Background="White" BorderThickness="1" CornerRadius="5" Padding="0">
<hc:SimpleStackPanel ClipToBounds="True" Orientation="Vertical" Height="300" Width="300" >
<Grid Margin="5" >
<hc:SimpleStackPanel ClipToBounds="True" Orientation="Vertical" Width="300" >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*" MinHeight="200"/>
<RowDefinition Height="*" MinHeight="100"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DockPanel Width="300" Grid.Row="0" HorizontalAlignment="Left" >
<TextBlock Margin="5,0" DockPanel.Dock="Left" Text="12312312" VerticalAlignment="Center"/>
<Button Click="DialogCloseBtn_Click" Margin="15,0" HorizontalAlignment="Right" DockPanel.Dock="Right" Content="X"/>
</DockPanel>
<Border CornerRadius="5" Grid.Row="0" Margin="0,0,0,10" Background="#d8d8d8">
<DockPanel Width="300" Grid.Row="0" HorizontalAlignment="Left" >
<TextBlock Margin="5,0" DockPanel.Dock="Left" Text="提示" VerticalAlignment="Center"/>
<Button Click="DialogCloseBtn_Click" Margin="5,0" HorizontalAlignment="Right" DockPanel.Dock="Right" Content="X"/>
</DockPanel>
</Border>
<TextBlock Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding ErrorMessage}"/>
<StackPanel Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Right">
<Button x:Name="DialogCloseBtn" Content="确定" Click="DialogCloseBtn_Click"/>
</StackPanel>
<Border CornerRadius="5" Grid.Row="2" Margin="0,10,0,0" Background="#b2b2b2">
<Grid>
<StackPanel Margin="5" VerticalAlignment="Center" HorizontalAlignment="Right">
<Button x:Name="DialogCloseBtn" Content="确定" Click="DialogCloseBtn_Click"/>
</StackPanel>
</Grid>
</Border>
</Grid>
</hc:SimpleStackPanel>
</Border>

View File

@ -5,34 +5,33 @@ using ExcelHelper.Services;
using ExcelHelper.Views;
using ExcelHelper.Views.ViewModels;
namespace ExcelHelper
namespace ExcelHelper;
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window, IView
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window, IView
private readonly MainViewModel ViewModel;
public MainWindow(MainViewModel viewModel, NavigationService navigationService)
{
private MainViewModel ViewModel;
public MainWindow(MainViewModel viewModel, NavigationService navigationService)
{
InitializeComponent();
DataContext = ViewModel = viewModel;
navigationService.InitForFrame(MainFrame);
InitializeComponent();
DataContext = ViewModel = viewModel;
navigationService.InitForFrame(MainFrame);
WeakReferenceMessenger.Default.Register<ErrorDialogMessage>(this, (r, message) =>
WeakReferenceMessenger.Default.Register<ErrorDialogMessage>(this, (r, message) =>
{
if (message.Value != null)
{
if (message.Value != null)
{
ViewModel.ErrorMessage = message.Value;
MessageDialog.Visibility = Visibility.Visible;
}
});
}
private void DialogCloseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
{
MessageDialog.Visibility = System.Windows.Visibility.Collapsed;
}
ViewModel.ErrorMessage = message.Value;
MessageDialog.Visibility = Visibility.Visible;
}
});
}
private void DialogCloseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
{
MessageDialog.Visibility = System.Windows.Visibility.Collapsed;
}
}

18
Model/TableColumnModel.cs Normal file
View File

@ -0,0 +1,18 @@
namespace ExcelHelper.Model
{
public class TableColumnModel
{
public string ExcelColumnName
{
get; set;
}
public string TableColumnName
{
get; set;
}
public string DataType
{
get; set;
}
}
}

View File

@ -3,25 +3,24 @@ using System.Threading.Tasks;
using ExcelHelper.Views.Pages;
using Microsoft.Extensions.Hosting;
namespace ExcelHelper.Services
namespace ExcelHelper.Services;
public class ExcelHelperHostedService : IHostedService
{
public class ExcelHelperHostedService : IHostedService
public Task StartAsync(CancellationToken cancellationToken)
{
public Task StartAsync(CancellationToken cancellationToken)
var mainWindow = App.AppHost.Get<MainWindow>();
if (mainWindow != null)
{
var mainWindow = App.AppHost.Get<MainWindow>();
if (mainWindow != null)
{
mainWindow.Show();
App.AppHost.Get<NavigationService>().NavigateTo<ImportExcelPage>();
}
return Task.CompletedTask;
mainWindow.Show();
App.AppHost.Get<NavigationService>().NavigateTo<ImportExcelPage>();
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}

View File

@ -2,34 +2,33 @@
using System.Windows.Controls;
using ExcelHelper.Views;
namespace ExcelHelper.Services
{
public class NavigationService
{
private Frame _frame;
public static string currentView;
namespace ExcelHelper.Services;
public void InitForFrame(Frame frame)
public class NavigationService
{
private Frame _frame;
public static string currentView;
public void InitForFrame(Frame frame)
{
_frame = frame;
}
public void NavigateTo<T>()
{
var target = App.AppHost.Get<T>();
if (target is IView page)
{
_frame = frame;
currentView = typeof(T).Name;
_frame.NavigationService.Navigate(page);
}
public void NavigateTo<T>()
}
public void NavigateTo(Type type)
{
var target = App.AppHost.Get(type);
if (target is IView page)
{
var target = App.AppHost.Get<T>();
if (target is IView page)
{
currentView = typeof(T).Name;
_frame.NavigationService.Navigate(page);
}
}
public void NavigateTo(Type type)
{
var target = App.AppHost.Get(type);
if (target is IView page)
{
currentView = type.Name;
_frame.NavigationService.Navigate(page);
}
currentView = type.Name;
_frame.NavigationService.Navigate(page);
}
}
}

View File

@ -57,8 +57,7 @@ public static class PasswordBoxHelper
private static void OnAttachPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
if (passwordBox == null)
if (sender is not PasswordBox passwordBox)
{
return;
}

View File

@ -1,6 +1,5 @@
namespace ExcelHelper.Views
namespace ExcelHelper.Views;
internal interface IView
{
internal interface IView
{
}
}

View File

@ -1,6 +1,5 @@
namespace ExcelHelper.Views
namespace ExcelHelper.Views;
internal interface IViewModel
{
internal interface IViewModel
{
}
}

View File

@ -1,15 +1,14 @@
using System.Windows.Controls;
namespace ExcelHelper.Views.Pages
namespace ExcelHelper.Views.Pages;
/// <summary>
/// DataListPage.xaml 的交互逻辑
/// </summary>
public partial class DataListPage : Page, IView
{
/// <summary>
/// DataListPage.xaml 的交互逻辑
/// </summary>
public partial class DataListPage : Page, IView
public DataListPage()
{
public DataListPage()
{
InitializeComponent();
}
InitializeComponent();
}
}

View File

@ -69,8 +69,7 @@
<hc:TabControl Grid.Column="0" Margin="5,5,7,5">
<hc:TabItem Header="预览">
<DataGrid
x:Name="ExcelDataPreviewGrid"
hc:DataGridAttach.ShowRowNumber="True"
x:Name="ExcelDataPreviewGrid"
AutoGenerateColumns="False"
EnableColumnVirtualization="True"
EnableRowVirtualization="True"
@ -85,9 +84,10 @@
<DataGrid
AutoGenerateColumns="False"
IsReadOnly="True"
ItemsSource="{Binding ExcelColumns, IsAsync=True}">
ItemsSource="{Binding TableColumns, IsAsync=True}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Header}" Header="列" />
<DataGridTextColumn Binding="{Binding ExcelColumnName}" Header="列名称" />
<DataGridTextColumn Binding="{Binding TableColumnName}" Header="生成表的列名称" />
</DataGrid.Columns>
</DataGrid>
</hc:TabItem>
@ -96,74 +96,132 @@
Grid.Column="0"
Width="2"
Margin="0,5" />
<GroupBox
Grid.Column="1"
Margin="5"
Padding="5">
<GroupBox.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="5,0"
VerticalAlignment="Center"
Text="参数配置" />
<Button
VerticalAlignment="Center"
Command="{Binding ReLoadExcelCommand}"
Content="重新读取Excel" />
<StackPanel Grid.Column="1"
Margin="5">
<GroupBox Padding="5">
<GroupBox.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="5,0"
VerticalAlignment="Center"
Text="参数配置" />
<Button Style="{StaticResource ButtonPrimary}"
VerticalAlignment="Center"
Command="{Binding ReLoadExcelCommand}"
Content="重新读取Excel" />
</StackPanel>
</GroupBox.Header>
<hc:SimpleStackPanel SnapsToDevicePixels="True">
<hc:SimpleStackPanel.Resources>
<Style TargetType="{x:Type hc:SimpleStackPanel}">
<Setter Property="Margin" Value="5,0" />
</Style>
</hc:SimpleStackPanel.Resources>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="指定的Sheet" />
<hc:ComboBox
MinWidth="60"
MaxWidth="180"
Margin="0"
ItemsSource="{Binding Sheets}"
SelectedValue="{Binding SelectedSheetName}" />
<Button
Margin="0"
VerticalAlignment="Center"
Command="{Binding ReadSheetsCommand}"
Content="刷新" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Height="Auto" Orientation="Horizontal">
<Label Content="起始位置:" />
<hc:TextBox MinWidth="40" Text="{Binding StartCell}" />
<CheckBox Content="包含列头" IsChecked="{Binding UseHeaderRow}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="结束位置:" />
<hc:TextBox MinWidth="40" Text="{Binding EndCell}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label>
<CheckBox Content="合并的单元格进行填充" IsChecked="{Binding FillMergedCells}" />
</Label>
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="最大读取行数:" />
<hc:NumericUpDown
MinWidth="40"
Minimum="0"
Maximum="300"
Value="{Binding MaxRow}" />
<TextBlock Margin="5,0" Text="预览时最大读取300行" VerticalAlignment="Center"/>
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Width="Auto" Orientation="Horizontal">
<Label Content="当前文件路径:" />
<!--<hc:TextBox MinWidth="200" />-->
<hc:ComboBox
MaxWidth="200"
ItemsSource="{Binding ExcelFiles}"
SelectedValue="{Binding CurrentFilePath}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel IsEnabled="False" Orientation="Horizontal">
<Label Content="Excel密码" />
<PasswordBox MinWidth="60" utils:PasswordBoxHelper.Password="{Binding ExcelPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="?" ToolTip="未加密留空多个Excel如果不同密码请分批次导入" />
</hc:SimpleStackPanel>
</hc:SimpleStackPanel>
</GroupBox>
<GroupBox Header="数据库配置" Padding="5">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="数据库类型"/>
<hc:ComboBox SelectedValuePath="Tag" SelectedValue="{Binding DbType}" MinWidth="100" >
<ComboBoxItem Tag="Sqlite" Content="Sqlite"/>
<ComboBoxItem Tag="SqlServer" Content="SqlServer"/>
<!--<ComboBoxItem Tag="MySql" Content="MySql/MariaDB"/>
<ComboBoxItem Tag="MongoDB" Content="MongoDB"/>
<ComboBoxItem Tag="PostgreSql" Content="PostgreSql"/>-->
</hc:ComboBox>
<CheckBox Content="加密连接" IsChecked="{Binding IsEncrypt}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<Label Content="地址:"/>
<hc:TextBox MinWidth="150" Text="{Binding DbServer}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="端口:"/>
<hc:TextBox MinWidth="50" Text="{Binding DbPort}" />
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<Label Content="账号:"/>
<hc:TextBox MinWidth="100" Text="{Binding DbUser}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="密码:"/>
<PasswordBox MinWidth="100" utils:PasswordBoxHelper.Password="{Binding DbPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="数据库:"/>
<hc:TextBox MinWidth="100" Text="{Binding DbName}" />
<Button Content="测试连接" Command="{Binding TestDbConnCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="导入后的数据表名称:"/>
<hc:TextBox MinWidth="100" Text="" />
<Button Style="{StaticResource ButtonPrimary}" Content="导入数据"/>
</StackPanel>
</StackPanel>
</GroupBox.Header>
<hc:SimpleStackPanel SnapsToDevicePixels="True">
<hc:SimpleStackPanel.Resources>
<Style TargetType="{x:Type hc:SimpleStackPanel}">
<Setter Property="Margin" Value="5,0" />
</Style>
</hc:SimpleStackPanel.Resources>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="指定的Sheet" />
<hc:ComboBox
MinWidth="60"
Margin="0"
ItemsSource="{Binding Sheets}"
SelectedValue="{Binding SelectedSheetName}" />
<Button
Margin="0"
VerticalAlignment="Center"
Command=""
Content="读取" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Height="Auto" Orientation="Horizontal">
<Label Content="起始位置:" />
<hc:TextBox MinWidth="40" Text="{Binding StartCell}" />
<CheckBox Content="包含列头" IsChecked="{Binding UseHeaderRow}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel IsEnabled="False" Orientation="Horizontal">
<Label Content="结束位置:" />
<hc:TextBox MinWidth="40" Text="{Binding EndCell}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="最大读取行数:" />
<hc:NumericUpDown
MinWidth="40"
Minimum="0"
Value="{Binding MaxRow}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Width="Auto" Orientation="Horizontal">
<Label Content="当前文件路径:" />
<!--<hc:TextBox MinWidth="200" />-->
<hc:ComboBox
MaxWidth="200"
ItemsSource="{Binding ExcelFiles}"
SelectedValue="{Binding CurrentFilePath}" />
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Orientation="Horizontal">
<Label Content="Excel密码" />
<PasswordBox MinWidth="60" utils:PasswordBoxHelper.Password="{Binding ExcelPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="?" ToolTip="未加密留空多个Excel如果不同密码请分批次导入" />
</hc:SimpleStackPanel>
</hc:SimpleStackPanel>
</GroupBox>
</GroupBox>
</StackPanel>
</Grid>
</Page>

View File

@ -3,64 +3,21 @@ using CommunityToolkit.Mvvm.Messaging;
using ExcelHelper.Message;
using ExcelHelper.Views.ViewModels;
namespace ExcelHelper.Views.Pages
namespace ExcelHelper.Views.Pages;
/// <summary>
/// ImportExcelPage.xaml 的交互逻辑
/// </summary>
public partial class ImportExcelPage : Page, IView, IRecipient<UpdateDataGridColumnsMessage>
{
/// <summary>
/// ImportExcelPage.xaml 的交互逻辑
/// </summary>
public partial class ImportExcelPage : Page, IView, IRecipient<UpdateDataGridColumnsMessage>
private readonly ImportViewModel ViewModel;
public ImportExcelPage(ImportViewModel viewModel)
{
private ImportViewModel ViewModel;
public ImportExcelPage(ImportViewModel viewModel)
{
InitializeComponent();
this.DataContext = ViewModel = viewModel;
ViewModel.IsActive = true;
// Register a message in some module
WeakReferenceMessenger.Default.Register<UpdateDataGridColumnsMessage>(this, (r, message) =>
{
if (message.Value != null)
{
ExcelDataPreviewGrid.Columns.Clear();
foreach (var column in message.Value)
{
ExcelDataPreviewGrid.Columns.Add(column);
}
}
});
}
private void Grid_DragEnter(object sender, System.Windows.DragEventArgs e)
{
if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
{
e.Effects = System.Windows.DragDropEffects.Link;
}
else
{
e.Effects = System.Windows.DragDropEffects.None;
}
DropFileMask.Visibility = System.Windows.Visibility.Visible;
}
private void Grid_Drop(object sender, System.Windows.DragEventArgs e)
{
DropFileMask.Visibility = System.Windows.Visibility.Collapsed;
if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
{
var files = (string[])e.Data.GetData(System.Windows.DataFormats.FileDrop);
if (files.Length > 0)
{
ViewModel.FileDrop(files);
}
}
}
private void Grid_DragLeave(object sender, System.Windows.DragEventArgs e)
{
DropFileMask.Visibility = System.Windows.Visibility.Collapsed;
}
void IRecipient<UpdateDataGridColumnsMessage>.Receive(UpdateDataGridColumnsMessage message)
InitializeComponent();
this.DataContext = ViewModel = viewModel;
ViewModel.IsActive = true;
// Register a message in some module
WeakReferenceMessenger.Default.Register<UpdateDataGridColumnsMessage>(this, (r, message) =>
{
if (message.Value != null)
{
@ -70,6 +27,48 @@ namespace ExcelHelper.Views.Pages
ExcelDataPreviewGrid.Columns.Add(column);
}
}
});
}
private void Grid_DragEnter(object sender, System.Windows.DragEventArgs e)
{
if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
{
e.Effects = System.Windows.DragDropEffects.Link;
}
else
{
e.Effects = System.Windows.DragDropEffects.None;
}
DropFileMask.Visibility = System.Windows.Visibility.Visible;
}
private void Grid_Drop(object sender, System.Windows.DragEventArgs e)
{
DropFileMask.Visibility = System.Windows.Visibility.Collapsed;
if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
{
var files = (string[])e.Data.GetData(System.Windows.DataFormats.FileDrop);
if (files.Length > 0)
{
ViewModel.FileDrop(files);
}
}
}
private void Grid_DragLeave(object sender, System.Windows.DragEventArgs e)
{
DropFileMask.Visibility = System.Windows.Visibility.Collapsed;
}
void IRecipient<UpdateDataGridColumnsMessage>.Receive(UpdateDataGridColumnsMessage message)
{
if (message.Value != null)
{
ExcelDataPreviewGrid.Columns.Clear();
foreach (var column in message.Value)
{
ExcelDataPreviewGrid.Columns.Add(column);
}
}
}
}

View File

@ -2,12 +2,16 @@
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 MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using SqlSugar;
namespace ExcelHelper.Views.ViewModels;
@ -31,15 +35,23 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
IsLoading = false;
}
public async void ReadForExcel(string path)
public async void ReadForExcel(string path, bool isReload = false)
{
IsLoading = true;
//await Task.Factory.StartNew(async () =>
//{
try
{
if (string.IsNullOrEmpty(path)) return;
var excelData = await MiniExcel.QueryAsync(path, sheetName: SelectedSheetName, useHeaderRow: UseHeaderRow, startCell: StartCell);
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));
@ -48,9 +60,20 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
{
ExcelData = excelData.Take(300);
}
var columns = MiniExcel.GetColumns(path, useHeaderRow: UseHeaderRow, startCell: StartCell, sheetName: SelectedSheetName);
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();
}
catch (Exception ex)
@ -58,18 +81,22 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
WeakReferenceMessenger.Default.Send(new ErrorDialogMessage($"出现了异常!{ex}"));
}
IsLoading = false;
//}).ContinueWith(x =>
// {
// });
}
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
@ -94,8 +121,20 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
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("未读取到列信息!"));
@ -105,31 +144,100 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
[RelayCommand]
private void OnReLoadExcel()
{
ReadForExcel(CurrentFilePath);
ReadForExcel(CurrentFilePath, isReload: true);
}
[RelayCommand]
private void OnReadSheets()
{
if (string.IsNullOrWhiteSpace(CurrentFilePath))
if (!string.IsNullOrWhiteSpace(CurrentFilePath))
{
GetSheets(CurrentFilePath);
SelectedSheetName = Sheets.FirstOrDefault();
}
}
private void GetSheets(string excelPath)
{
var sheets = MiniExcel.GetSheetNames(excelPath);
if (Sheets == null)
{
Sheets = new ObservableCollection<string>();
Sheets = [];
}
else
{
Sheets.Clear();
}
MiniExcel.GetSheetNames(excelPath)?.ForEach(sheetName =>
sheets.ForEach(sheetName =>
{
Sheets.Add(sheetName);
});
SelectedSheetName = Sheets.FirstOrDefault();
}
[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
@ -142,6 +250,9 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
[ObservableProperty]
private ObservableCollection<DataGridColumn> _excelColumns = [];
[ObservableProperty]
private ObservableCollection<TableColumnModel> _tableColumns = [];
/// <summary>
/// 是否正在加载
/// </summary>
@ -175,6 +286,13 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
/// </summary>
[ObservableProperty]
private string _endCell;
/// <summary>
/// 使用首行作为表头
/// </summary>
[ObservableProperty]
private bool _fillMergedCells = false;
/// <summary>
/// 最大行数
/// </summary>
@ -201,5 +319,30 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
[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;
#endregion
}

View File

@ -3,32 +3,31 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ExcelHelper.Views.Pages;
namespace ExcelHelper.Views.ViewModels
namespace ExcelHelper.Views.ViewModels;
public partial class MainViewModel : ObservableObject, IViewModel
{
public partial class MainViewModel : ObservableObject, IViewModel
/// <summary>
/// 异常信息
/// </summary>
[ObservableProperty]
private string _errorMessage;
[RelayCommand]
private void OnSideMenuSelect(string itemTag)
{
/// <summary>
/// 异常信息
/// </summary>
[ObservableProperty]
private string _errorMessage;
[RelayCommand]
private void OnSideMenuSelect(string itemTag)
Trace.WriteLine($"OnSideMenuSelect -> {itemTag}");
var targetPage = itemTag switch
{
Trace.WriteLine($"OnSideMenuSelect -> {itemTag}");
var targetPage = itemTag switch
{
"ImportExcelPage" => typeof(ImportExcelPage),
"DataListPage" => typeof(DataListPage),
_ => null
};
if (targetPage != null)
{
App.AppHost.Get<Services.NavigationService>().NavigateTo(targetPage);
}
"ImportExcelPage" => typeof(ImportExcelPage),
"DataListPage" => typeof(DataListPage),
_ => null
};
if (targetPage != null)
{
App.AppHost.Get<Services.NavigationService>().NavigateTo(targetPage);
}
}
}