Sfoglia il codice sorgente

Добавлен экспорт в docx

Ahatov Artur 5 mesi fa
parent
commit
5be4981341

+ 29 - 1
src/DontHarmDesktop/DontHarmDesktop.csproj

@@ -318,6 +318,34 @@
       <LastGenOutput>DontHarmModel.cs</LastGenOutput>
     </Content>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <COMReference Include="Microsoft.Office.Core">
+      <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
+      <VersionMajor>2</VersionMajor>
+      <VersionMinor>8</VersionMinor>
+      <Lcid>0</Lcid>
+      <WrapperTool>primary</WrapperTool>
+      <Isolated>False</Isolated>
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </COMReference>
+    <COMReference Include="Microsoft.Office.Interop.Word">
+      <Guid>{00020905-0000-0000-C000-000000000046}</Guid>
+      <VersionMajor>8</VersionMajor>
+      <VersionMinor>7</VersionMinor>
+      <Lcid>0</Lcid>
+      <WrapperTool>primary</WrapperTool>
+      <Isolated>False</Isolated>
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </COMReference>
+    <COMReference Include="VBIDE">
+      <Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
+      <VersionMajor>5</VersionMajor>
+      <VersionMinor>3</VersionMinor>
+      <Lcid>0</Lcid>
+      <WrapperTool>primary</WrapperTool>
+      <Isolated>False</Isolated>
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </COMReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 23 - 16
src/DontHarmDesktop/Pages/Reports/EmployeeCost.xaml

@@ -17,6 +17,8 @@
                 <RowDefinition/>
                 <RowDefinition/>
                 <RowDefinition/>
+                <RowDefinition/>
+                <RowDefinition/>
             </Grid.RowDefinitions>
 
             <Grid.ColumnDefinitions>
@@ -28,21 +30,25 @@
                 Grid.Row="0"
                 Style="{StaticResource BackButton}"
                 Command="{Binding Source={x:Static root:Navigation.GoBack}}"/>
+            <Button 
+                Grid.Row="1"
+                Margin="0,4,0,0"
+                Content="Сформировать"
+                Command="{Binding StartCmd}"/>
+            <Button 
+                Grid.Row="2"
+                Margin="0,4,0,0"
+                Content="Экспорт в CSV"
+                Command="{Binding ExportCsvCmd}"/>
+            <Button 
+                Grid.Row="3"
+                Margin="0,4,0,0"
+                Content="Экспорт в DOCX"
+                Command="{Binding ExportDocxCmd}"/>
 
-            <StackPanel Grid.Row="1">
-                <Button 
-                    Margin="0,4,0,0"
-                    Content="Сформировать"
-                    Command="{Binding StartCmd}"/>
-                <Button 
-                    Margin="0,4,0,0"
-                    Content="Экспорт в CSV"
-                    Command="{Binding ExportCmd}"/>
-            </StackPanel>
-            
-            
             <Grid
-                Grid.Row="1"
+                Grid.Row="0"
+                Grid.RowSpan="3"
                 Grid.Column="1"
                 Margin="4">
 
@@ -73,7 +79,7 @@
             </Grid>
 
             <WindowsFormsHost 
-                Grid.Row="2"
+                Grid.Row="4"
                 Grid.ColumnSpan="2"
                 Height="Auto" 
                 VerticalAlignment="Top">
@@ -89,12 +95,13 @@
 
                     <charts:Chart.Series>
                         <charts:Series
-                            x:Name="DefaultSeries"
                             ChartArea="Default"
+                            x:Name="DefaultSeries"
                             Name="Среднее арифметическое стоимости услуг"
                             IsValueShownAsLabel="True"
                             ChartType="Bar" 
-                            Legend="Default"/>
+                            Legend="Default">
+                        </charts:Series>
                     </charts:Chart.Series>
 
                 </charts:Chart>

+ 2 - 1
src/DontHarmDesktop/Pages/Reports/EmployeeCost.xaml.cs

@@ -23,8 +23,9 @@ namespace DontHarmDesktop.Pages.Reports
         public EmployeeCost()
         {
             InitializeComponent();
+
             DataContext = new ViewModels.Reports.EmployeeCostVM(
-                this.DefaultSeries
+                DefaultSeries
             );
         }
     }

+ 106 - 6
src/DontHarmDesktop/ViewModels/Reports/EmployeeCostVM.cs

@@ -4,11 +4,14 @@ using System.Collections.Generic;
 using System.Data.Entity;
 using System.Linq;
 using System.Text;
-using System.Windows.Forms.DataVisualization.Charting;
+using Charting = System.Windows.Forms.DataVisualization.Charting;
 using CsvHelper;
 using CsvHelper.Configuration.Attributes;
 using System.IO;
 using System.Globalization;
+using System.Windows;
+using Word = Microsoft.Office.Interop.Word;
+using System;
 
 // https://www.c-sharpcorner.com/article/static-and-dynamic-line-chart-in-wpf-with-mvvm-pattern-using-prism-library/
 
@@ -31,9 +34,14 @@ namespace DontHarmDesktop.ViewModels.Reports
         public DelegateCommand StartCmd { get; set; }
 
         /// <summary>
-        /// Команда "Экспортировать"
+        /// Команда "Экспортировать в CSV"
         /// </summary>
-        public DelegateCommand ExportCmd { get; set; }
+        public DelegateCommand ExportCsvCmd { get; set; }
+
+        /// <summary>
+        /// Команда "Экспортировать в DOCX"
+        /// </summary>
+        public DelegateCommand ExportDocxCmd { get; set; }
 
         /// <summary>
         /// Даные для графика
@@ -43,7 +51,7 @@ namespace DontHarmDesktop.ViewModels.Reports
         /// <summary>
         /// Интерфейс для отображения точек
         /// </summary>
-        private readonly Series SeriesInterface;
+        private readonly Charting.Series SeriesInterface;
 
         /// <summary>
         /// Фильтр по имени
@@ -58,10 +66,11 @@ namespace DontHarmDesktop.ViewModels.Reports
         /// </summary>
         public int PriceIndex { get; set; }
 
-        public EmployeeCostVM(Series series) 
+        public EmployeeCostVM(Charting.Series series) 
         {
             StartCmd = new DelegateCommand(StartExecuted);
-            ExportCmd = new DelegateCommand(ExportExecuted);
+            ExportCsvCmd = new DelegateCommand(ExportExecuted);
+            ExportDocxCmd = new DelegateCommand(ExportDocxExecuted);
             Costs = new List<CostItem>();
             SeriesInterface = series;
             FilterName = "";
@@ -101,6 +110,97 @@ namespace DontHarmDesktop.ViewModels.Reports
                     });
                 }
             }
+
+            // 3. Profit
+            MessageBox.Show("Экспорт успешен", "Завершение", MessageBoxButton.OK, MessageBoxImage.Information);
+        }
+
+        public void ExportDocxExecuted()
+        {
+            if (Costs.Count == 0)
+            {
+                return;
+            }
+
+            // 1. Показать диалог выбора файла
+            var ofd = new Microsoft.Win32.SaveFileDialog
+            {
+                Filter = "DOCX файлы (*.docx)|*.docx|Все файлы (*.*)|*.*"
+            };
+            bool? selected = ofd.ShowDialog();
+            if (selected == false)
+            {
+                return;
+            }
+            string fileName = ofd.FileName;
+
+            // 2. Сгенерировать DOCX
+            var app = new Word.Application();
+            var doc = app.Documents.Add();
+
+            // 2.1 Добавление заголовка
+            var heading = doc.Paragraphs.Add();
+            var headingRange = heading.Range;
+            headingRange.Text = "Ценность сотрудников";
+            heading.set_Style("Заголовок"); // зависит от текущего языка
+            headingRange.InsertParagraphAfter();
+
+            // 2.2 Добавление таблицы
+            var tableP = doc.Paragraphs.Add();
+            var tableRange = tableP.Range;
+            var table = doc.Tables.Add(tableRange, Costs.Count + 1, 2);
+            table.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle;
+            table.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingle;
+            table.Range.Cells.VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalTop;
+
+            // 2.3 Заголовок таблицы
+            table.Cell(1, 1).Range.Text = "Сотрудник";
+            table.Cell(1, 2).Range.Text = "Ценность в среднем";
+            table.Rows[1].Range.Bold = 1;
+            table.Rows[1].Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
+
+            // 2.4 Данные таблицы
+            int rowIndex = 2;
+            CostItem maxPriceness = null;
+            CostItem minPriceness = null;
+            
+            Costs.ForEach(c =>
+            {
+                if (rowIndex == 2)
+                {
+                    maxPriceness = c;
+                    minPriceness = c;
+                }
+                else
+                {
+                    maxPriceness = c.Priceness > maxPriceness.Priceness ? c : maxPriceness;
+                    minPriceness = c.Priceness < minPriceness.Priceness ? c : minPriceness;
+                }
+                
+                table.Cell(rowIndex, 1).Range.Text = c.HumanName;
+                table.Cell(rowIndex, 2).Range.Text = c.Priceness.ToString();
+                
+                rowIndex++;
+            });
+
+            // 2.5 Макс/мин
+            var maxP = doc.Paragraphs.Add();
+            var maxPRange = maxP.Range;
+            maxPRange.Font.Color = Word.WdColor.wdColorBlueGray;
+            maxPRange.Text = $"Сотрудник с наибольшей ценностью: {maxPriceness.HumanName} -- {maxPriceness.Priceness}";
+            maxPRange.InsertParagraphAfter();
+            
+            var minP = doc.Paragraphs.Add();
+            var minPRange = minP.Range;
+            minPRange.Font.Color = Word.WdColor.wdColorBlueGray;
+            minPRange.Text = $"Сотрудник с наименьшей ценностью: {minPriceness.HumanName} -- {minPriceness.Priceness}";
+
+            // 3 Сохранение
+            doc.SaveAs2(fileName);
+            app.Visible = true;
+
+            // 4. Profit
+            MessageBox.Show("Экспорт успешен", "Завершение", MessageBoxButton.OK, MessageBoxImage.Information);
         }
 
         private async void Refresh()