Update
This commit is contained in:
parent
05b41a5685
commit
bad4552f16
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
namespace ExcelHelper.Views
|
||||
namespace ExcelHelper.Views;
|
||||
|
||||
internal interface IView
|
||||
{
|
||||
internal interface IView
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
namespace ExcelHelper.Views
|
||||
namespace ExcelHelper.Views;
|
||||
|
||||
internal interface IViewModel
|
||||
{
|
||||
internal interface IViewModel
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue