Adiciona importação de Excel e melhorias gerais
Adicionada funcionalidade para importar contatos de arquivos Excel usando a biblioteca ClosedXML, incluindo o comando `ImportExcelCommand` e o método `ImportExcelAsync` na classe `MainWindowViewModel`. Ajustado o layout da interface gráfica para incluir um botão "Importar". Outras alterações incluem: - Adição de pacotes ao projeto (`ClosedXML`, `Dapper`, etc.). - Ajustes no cálculo de `gridWidth` e `gridHeight` em `ImageService`. - Alteração do valor da constante `OverlayOffset` em `ImageService`. - Refatoração do método `SaveBitmap` para tratamento de exceções. - Correção na substituição de extensão ao salvar imagens. - Reorganização de inicialização de coleções em `MainWindowViewModel`. Essas mudanças melhoram a funcionalidade e a consistência do projeto.
This commit is contained in:
parent
1badf9db58
commit
5231c5cf9d
@ -15,6 +15,7 @@
|
|||||||
<Content Include="smart.ico" />
|
<Content Include="smart.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="ClosedXML" Version="0.105.0" />
|
||||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.3.25171.5" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.3.25171.5" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-preview.3.25171.5" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-preview.3.25171.5" />
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace BackgroundBuilder.Services
|
|||||||
{
|
{
|
||||||
|
|
||||||
// no longer injected — use a private constant
|
// no longer injected — use a private constant
|
||||||
private static readonly Thickness OverlayOffset = new(10, 58, 10, 58);
|
private static readonly Thickness OverlayOffset = new(10, 53, 10, 53);
|
||||||
|
|
||||||
public async Task<BitmapImage> LoadAsync(string path)
|
public async Task<BitmapImage> LoadAsync(string path)
|
||||||
{
|
{
|
||||||
@ -88,8 +88,8 @@ namespace BackgroundBuilder.Services
|
|||||||
x = width - scaledWidth - offset.Right;
|
x = width - scaledWidth - offset.Right;
|
||||||
y = height - scaledHeight - offset.Bottom;
|
y = height - scaledHeight - offset.Bottom;
|
||||||
|
|
||||||
gridWidth = scaledWidth + offset.Right;
|
gridWidth = scaledWidth;
|
||||||
gridHeight = scaledHeight + offset.Bottom;
|
gridHeight = scaledHeight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -161,6 +161,8 @@ namespace BackgroundBuilder.Services
|
|||||||
/// Encodes the given bitmap as PNG and writes it to disk.
|
/// Encodes the given bitmap as PNG and writes it to disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void SaveBitmap(RenderTargetBitmap bitmap, string path)
|
private static void SaveBitmap(RenderTargetBitmap bitmap, string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var directory = Path.GetDirectoryName(path);
|
var directory = Path.GetDirectoryName(path);
|
||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
@ -173,5 +175,10 @@ namespace BackgroundBuilder.Services
|
|||||||
encoder.Frames.Add(BitmapFrame.Create(bitmap));
|
encoder.Frames.Add(BitmapFrame.Create(bitmap));
|
||||||
encoder.Save(fs);
|
encoder.Save(fs);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Erro ao salvar a imagem:\n{ex.Message}\n\nCaminho: {path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ using BackgroundBuilder.Models;
|
|||||||
using BackgroundBuilder.Repositories;
|
using BackgroundBuilder.Repositories;
|
||||||
using BackgroundBuilder.Services;
|
using BackgroundBuilder.Services;
|
||||||
using BackgroundBuilder.Utils;
|
using BackgroundBuilder.Utils;
|
||||||
|
using ClosedXML.Excel;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace BackgroundBuilder.ViewModels
|
namespace BackgroundBuilder.ViewModels
|
||||||
@ -29,8 +30,8 @@ namespace BackgroundBuilder.ViewModels
|
|||||||
public ObservableCollection<Contato> Comando { get; } = [];
|
public ObservableCollection<Contato> Comando { get; } = [];
|
||||||
public ObservableCollection<Contato> Aniversarios { get; } = [];
|
public ObservableCollection<Contato> Aniversarios { get; } = [];
|
||||||
|
|
||||||
public ObservableCollection<Contato> ContatosSemCMDFirstHalf { get; } = new();
|
public ObservableCollection<Contato> ContatosSemCMDFirstHalf { get; } = [];
|
||||||
public ObservableCollection<Contato> ContatosSemCMDSecondHalf { get; } = new();
|
public ObservableCollection<Contato> ContatosSemCMDSecondHalf { get; } = [];
|
||||||
|
|
||||||
|
|
||||||
private Contato? _selectedContato;
|
private Contato? _selectedContato;
|
||||||
@ -60,6 +61,7 @@ namespace BackgroundBuilder.ViewModels
|
|||||||
public ICommand RefreshCommand { get; }
|
public ICommand RefreshCommand { get; }
|
||||||
public RelayCommand UpdateCommand { get; }
|
public RelayCommand UpdateCommand { get; }
|
||||||
public RelayCommand ExportImageCommand { get; }
|
public RelayCommand ExportImageCommand { get; }
|
||||||
|
public RelayCommand ImportExcelCommand { get; }
|
||||||
|
|
||||||
public MainWindowViewModel(
|
public MainWindowViewModel(
|
||||||
IContatoRepository repo,
|
IContatoRepository repo,
|
||||||
@ -78,6 +80,7 @@ namespace BackgroundBuilder.ViewModels
|
|||||||
RefreshCommand = new RelayCommand(async _ => await LoadRawAsync());
|
RefreshCommand = new RelayCommand(async _ => await LoadRawAsync());
|
||||||
UpdateCommand = new RelayCommand(async _ => await UpdateAsync(), _ => SelectedContatos != null);
|
UpdateCommand = new RelayCommand(async _ => await UpdateAsync(), _ => SelectedContatos != null);
|
||||||
ExportImageCommand = new RelayCommand(async _ => await RenderImageAsync(), _ => BackgroundImage != null && OverlayElement != null);
|
ExportImageCommand = new RelayCommand(async _ => await RenderImageAsync(), _ => BackgroundImage != null && OverlayElement != null);
|
||||||
|
ImportExcelCommand = new RelayCommand(async _ => await ImportExcelAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshTaskbarInfo()
|
public void RefreshTaskbarInfo()
|
||||||
@ -161,7 +164,7 @@ namespace BackgroundBuilder.ViewModels
|
|||||||
&& OverlayElement is FrameworkElement overlay
|
&& OverlayElement is FrameworkElement overlay
|
||||||
&& BackgroundImage is BitmapImage bg)
|
&& BackgroundImage is BitmapImage bg)
|
||||||
{
|
{
|
||||||
await _imageService.SaveAsync(overlay, bg, dlg.FileName, dlg.FileName.Replace(".", "_1."));
|
await _imageService.SaveAsync(overlay, bg, dlg.FileName, dlg.FileName.Replace(".png", "_1.png"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,5 +242,52 @@ namespace BackgroundBuilder.ViewModels
|
|||||||
ContatosSemCMDSecondHalf.Add(list[i]);
|
ContatosSemCMDSecondHalf.Add(list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ImportExcelAsync()
|
||||||
|
{
|
||||||
|
var openFileDialog = new OpenFileDialog
|
||||||
|
{
|
||||||
|
Filter = "Excel Files|*.xlsx;*.xls"
|
||||||
|
};
|
||||||
|
if (openFileDialog.ShowDialog() != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var filePath = openFileDialog.FileName;
|
||||||
|
var ramais = new List<Contato>();
|
||||||
|
|
||||||
|
using (var workbook = new XLWorkbook(filePath))
|
||||||
|
{
|
||||||
|
var ws = workbook.Worksheets.First();
|
||||||
|
var table = ws.Cell("B2").CurrentRegion;
|
||||||
|
|
||||||
|
foreach (var row in table.Rows().Skip(1)) // Skip header
|
||||||
|
{
|
||||||
|
var contato = new Contato
|
||||||
|
{
|
||||||
|
Ramal = row.Cell(3).GetString(),
|
||||||
|
Nome = row.Cell(1).GetString(),
|
||||||
|
Email = row.Cell(2).GetString(),
|
||||||
|
Area = row.Cell(4).GetString(),
|
||||||
|
IsComando = false
|
||||||
|
};
|
||||||
|
ramais.Add(contato);
|
||||||
|
}
|
||||||
|
|
||||||
|
table = ws.Cell("G2").CurrentRegion;
|
||||||
|
|
||||||
|
foreach (var row in table.Rows().Skip(1)) // Skip header
|
||||||
|
{
|
||||||
|
ramais.Find(x => x.Nome == row.Cell(1).GetString()).Aniversario = row.Cell(2).GetDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var contato in ramais)
|
||||||
|
{
|
||||||
|
await _repo.InsertUpdateAsync(contato);
|
||||||
|
}
|
||||||
|
|
||||||
|
await LoadRawAsync(); // Refresh UI
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,6 +135,7 @@
|
|||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<!-- Row 2: Image-->
|
<!-- Row 2: Image-->
|
||||||
<Rectangle Grid.Column="0"
|
<Rectangle Grid.Column="0"
|
||||||
@ -156,16 +157,23 @@
|
|||||||
Padding="20,3,20,3"
|
Padding="20,3,20,3"
|
||||||
Height="40"
|
Height="40"
|
||||||
Margin="5"/>
|
Margin="5"/>
|
||||||
|
<Button Content="Importar"
|
||||||
|
Command="{Binding ImportExcelCommand}"
|
||||||
|
Grid.Column="3"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Padding="20,3,20,3"
|
||||||
|
Height="40"
|
||||||
|
Margin="5"/>
|
||||||
<Button Content="Recarregar Contatos"
|
<Button Content="Recarregar Contatos"
|
||||||
Command="{Binding RefreshCommand}"
|
Command="{Binding RefreshCommand}"
|
||||||
Grid.Column="3"
|
Grid.Column="4"
|
||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
Padding="5"
|
Padding="5"
|
||||||
Height="40"
|
Height="40"
|
||||||
Margin="5"/>
|
Margin="5"/>
|
||||||
<Button Content="+ Nova linha"
|
<Button Content="+ Nova linha"
|
||||||
Command="{Binding AddCommand}"
|
Command="{Binding AddCommand}"
|
||||||
Grid.Column = "4"
|
Grid.Column = "5"
|
||||||
Foreground="Green"
|
Foreground="Green"
|
||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
Padding="5"
|
Padding="5"
|
||||||
@ -173,7 +181,7 @@
|
|||||||
Margin="5"/>
|
Margin="5"/>
|
||||||
<Button Content="- Deletar selecionada"
|
<Button Content="- Deletar selecionada"
|
||||||
Command="{Binding DeleteCommand}"
|
Command="{Binding DeleteCommand}"
|
||||||
Grid.Column = "5"
|
Grid.Column = "6"
|
||||||
Foreground="Red"
|
Foreground="Red"
|
||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
Padding="5"
|
Padding="5"
|
||||||
@ -182,7 +190,7 @@
|
|||||||
<Button Content="Salvar dados"
|
<Button Content="Salvar dados"
|
||||||
Command="{Binding UpdateCommand}"
|
Command="{Binding UpdateCommand}"
|
||||||
CommandParameter="RawGrid"
|
CommandParameter="RawGrid"
|
||||||
Grid.Column = "6"
|
Grid.Column = "7"
|
||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
Padding="5"
|
Padding="5"
|
||||||
Height="40"
|
Height="40"
|
||||||
@ -190,7 +198,7 @@
|
|||||||
<Button Content="Criar Imagem -->"
|
<Button Content="Criar Imagem -->"
|
||||||
Command="{Binding ExportImageCommand}"
|
Command="{Binding ExportImageCommand}"
|
||||||
CommandParameter="MainGrid"
|
CommandParameter="MainGrid"
|
||||||
Grid.Column = "7"
|
Grid.Column = "8"
|
||||||
Foreground="Blue"
|
Foreground="Blue"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Padding="5"
|
Padding="5"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user