отчет ворд
This commit is contained in:
parent
79527c933a
commit
81e3bee0e5
@ -1,4 +1,7 @@
|
|||||||
using CarServiceContracts.BindingModels;
|
using BlacksmithWorkshopBusinessLogic.OfficePackage;
|
||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels;
|
||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.Implements;
|
||||||
|
using CarServiceContracts.BindingModels;
|
||||||
using CarServiceContracts.BusinessLogicsContracts;
|
using CarServiceContracts.BusinessLogicsContracts;
|
||||||
using CarServiceContracts.StorageContracts;
|
using CarServiceContracts.StorageContracts;
|
||||||
using CarServiceContracts.ViewModels;
|
using CarServiceContracts.ViewModels;
|
||||||
@ -11,11 +14,14 @@ namespace CarServiceBusinessLogic.BusinessLogics
|
|||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IWorkStorage _workStorage;
|
private readonly IWorkStorage _workStorage;
|
||||||
private readonly IWorkPaymentStorage _workPaymentStorage;
|
private readonly IWorkPaymentStorage _workPaymentStorage;
|
||||||
public ReportLogic(ILogger<ReportLogic> logger, IWorkStorage workStorage, IWorkPaymentStorage workPaymentStorage)
|
private readonly AbstractSaveToWord _saveToWord;
|
||||||
|
|
||||||
|
public ReportLogic(ILogger<ReportLogic> logger, IWorkStorage workStorage, IWorkPaymentStorage workPaymentStorage, AbstractSaveToWord saveToWord)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_workStorage = workStorage;
|
_workStorage = workStorage;
|
||||||
_workPaymentStorage = workPaymentStorage;
|
_workPaymentStorage = workPaymentStorage;
|
||||||
|
_saveToWord = saveToWord;
|
||||||
}
|
}
|
||||||
public List<ReportWorkWithRequestsViewModel> GetRequestsByWorks(ReportBindingModel model)
|
public List<ReportWorkWithRequestsViewModel> GetRequestsByWorks(ReportBindingModel model)
|
||||||
{
|
{
|
||||||
@ -29,7 +35,12 @@ namespace CarServiceBusinessLogic.BusinessLogics
|
|||||||
}
|
}
|
||||||
public void SaveComponentsToWordFile(ReportBindingModel model)
|
public void SaveComponentsToWordFile(ReportBindingModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_saveToWord.CreateDoc(new WordInfo
|
||||||
|
{
|
||||||
|
FileName = model.FileName,
|
||||||
|
Title = "Список заявок",
|
||||||
|
WorksWithRequests = GetRequestsByWorks(model)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public void SaveManufactureComponentToExcelFile(ReportBindingModel model)
|
public void SaveManufactureComponentToExcelFile(ReportBindingModel model)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||||
|
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage
|
||||||
|
{
|
||||||
|
public abstract class AbstractSaveToWord
|
||||||
|
{
|
||||||
|
public void CreateDoc(WordInfo info)
|
||||||
|
{
|
||||||
|
CreateWord(info);
|
||||||
|
CreateParagraph(new WordParagraph
|
||||||
|
{
|
||||||
|
Texts = new List<(string, WordTextProperties)>
|
||||||
|
{
|
||||||
|
(info.Title, new WordTextProperties { Bold = true, Size = "24", })
|
||||||
|
},
|
||||||
|
TextProperties = new WordTextProperties
|
||||||
|
{
|
||||||
|
Size = "24",
|
||||||
|
JustificationType = WordJustificationType.Center
|
||||||
|
}
|
||||||
|
});
|
||||||
|
foreach (var WWR in info.WorksWithRequests)
|
||||||
|
{
|
||||||
|
CreateParagraph(new WordParagraph
|
||||||
|
{
|
||||||
|
Texts = new List<(string, WordTextProperties)>
|
||||||
|
{
|
||||||
|
(WWR.WorkName, new WordTextProperties { Bold = true, Size = "24", })
|
||||||
|
},
|
||||||
|
TextProperties = new WordTextProperties
|
||||||
|
{
|
||||||
|
Size = "24",
|
||||||
|
JustificationType = WordJustificationType.Both
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (WWR.RepairRequests.Count == 0)
|
||||||
|
{
|
||||||
|
CreateParagraph(new WordParagraph
|
||||||
|
{
|
||||||
|
Texts = new List<(string, WordTextProperties)>
|
||||||
|
{
|
||||||
|
("Заявок по работе нет", new WordTextProperties { Size = "24", })
|
||||||
|
},
|
||||||
|
TextProperties = new WordTextProperties
|
||||||
|
{
|
||||||
|
Size = "24",
|
||||||
|
JustificationType = WordJustificationType.Both
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
foreach (var RR in WWR.RepairRequests)
|
||||||
|
{
|
||||||
|
|
||||||
|
CreateParagraph(new WordParagraph
|
||||||
|
{
|
||||||
|
Texts = new List<(string, WordTextProperties)>
|
||||||
|
{
|
||||||
|
($"Заявка № {RR.RepairRequestId} от {RR.RepairRequestDateCreated}. Заказчик - {RR.CustomerName}. Транспортное средство - {RR.VehicleName}, гос. номер {RR.Plate}. Количество работ: {RR.WorksCount}", new WordTextProperties { Size = "24", })
|
||||||
|
},
|
||||||
|
TextProperties = new WordTextProperties
|
||||||
|
{
|
||||||
|
Size = "24",
|
||||||
|
JustificationType = WordJustificationType.Both
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SaveWord(info);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Создание doc-файла
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info"></param>
|
||||||
|
protected abstract void CreateWord(WordInfo info);
|
||||||
|
/// <summary>
|
||||||
|
/// Создание абзаца с текстом
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paragraph"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract void CreateParagraph(WordParagraph paragraph);
|
||||||
|
/// <summary>
|
||||||
|
/// Сохранение файла
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info"></param>
|
||||||
|
protected abstract void SaveWord(WordInfo info);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums
|
||||||
|
{
|
||||||
|
public enum ExcelStyleInfoType
|
||||||
|
{
|
||||||
|
Title,
|
||||||
|
Text,
|
||||||
|
TextWithBorder
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums
|
||||||
|
{
|
||||||
|
public enum PdfParagraphAlignmentType
|
||||||
|
{
|
||||||
|
Center,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums
|
||||||
|
{
|
||||||
|
public enum WordJustificationType
|
||||||
|
{
|
||||||
|
Center,
|
||||||
|
Both
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class ExcelCellParameters
|
||||||
|
{
|
||||||
|
public string ColumnName { get; set; } = string.Empty;
|
||||||
|
public uint RowIndex { get; set; }
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
public string CellReference => $"{ColumnName}{RowIndex}";
|
||||||
|
public ExcelStyleInfoType StyleInfo { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
using CarServiceContracts.ViewModels;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class ExcelInfo
|
||||||
|
{
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
public List<ReportWorkWithRequestsViewModel> WorksWithRequests { get; set; } = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class ExcelMergeParameters
|
||||||
|
{
|
||||||
|
public string CellFromName { get; set; } = string.Empty;
|
||||||
|
public string CellToName { get; set; } = string.Empty;
|
||||||
|
public string Merge => $"{CellFromName}:{CellToName}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
using CarServiceContracts.ViewModels;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class PdfInfo
|
||||||
|
{
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
public DateTime DateFrom { get; set; }
|
||||||
|
public DateTime DateTo { get; set; }
|
||||||
|
public List<ReportWorksWithPaymentsViewModel> Payments { get; set; } = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class PdfParagraph
|
||||||
|
{
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
public string Style { get; set; } = string.Empty;
|
||||||
|
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class PdfRowParameters
|
||||||
|
{
|
||||||
|
public List<string> Texts { get; set; } = new();
|
||||||
|
public string Style { get; set; } = string.Empty;
|
||||||
|
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using CarServiceContracts.ViewModels;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class WordInfo
|
||||||
|
{
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
public List<ReportWorkWithRequestsViewModel> WorksWithRequests { get; set; } = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class WordParagraph
|
||||||
|
{
|
||||||
|
public List<(string, WordTextProperties)> Texts { get; set; } = new();
|
||||||
|
public WordTextProperties? TextProperties { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels
|
||||||
|
{
|
||||||
|
public class WordTextProperties
|
||||||
|
{
|
||||||
|
public string Size { get; set; } = string.Empty;
|
||||||
|
public bool Bold { get; set; }
|
||||||
|
public WordJustificationType JustificationType { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperEnums;
|
||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels;
|
||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Wordprocessing;
|
||||||
|
using DocumentFormat.OpenXml;
|
||||||
|
|
||||||
|
namespace BlacksmithWorkshopBusinessLogic.OfficePackage.Implements
|
||||||
|
{
|
||||||
|
public class SaveToWord : AbstractSaveToWord
|
||||||
|
{
|
||||||
|
private WordprocessingDocument? _wordDocument;
|
||||||
|
private Body? _docBody;
|
||||||
|
/// <summary>
|
||||||
|
/// Получение типа выравнивания
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static JustificationValues GetJustificationValues(WordJustificationType type)
|
||||||
|
{
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
WordJustificationType.Both => JustificationValues.Both,
|
||||||
|
WordJustificationType.Center => JustificationValues.Center,
|
||||||
|
_ => JustificationValues.Left,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Настройки страницы
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static SectionProperties CreateSectionProperties()
|
||||||
|
{
|
||||||
|
var properties = new SectionProperties();
|
||||||
|
var pageSize = new PageSize
|
||||||
|
{
|
||||||
|
Orient = PageOrientationValues.Portrait
|
||||||
|
};
|
||||||
|
properties.AppendChild(pageSize);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Задание форматирования для абзаца
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paragraphProperties"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties)
|
||||||
|
{
|
||||||
|
if (paragraphProperties == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var properties = new ParagraphProperties();
|
||||||
|
properties.AppendChild(new Justification()
|
||||||
|
{
|
||||||
|
Val =
|
||||||
|
GetJustificationValues(paragraphProperties.JustificationType)
|
||||||
|
});
|
||||||
|
properties.AppendChild(new SpacingBetweenLines
|
||||||
|
{
|
||||||
|
LineRule = LineSpacingRuleValues.Auto
|
||||||
|
});
|
||||||
|
properties.AppendChild(new Indentation());
|
||||||
|
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
|
||||||
|
if (!string.IsNullOrEmpty(paragraphProperties.Size))
|
||||||
|
{
|
||||||
|
paragraphMarkRunProperties.AppendChild(new FontSize
|
||||||
|
{
|
||||||
|
Val =
|
||||||
|
paragraphProperties.Size
|
||||||
|
});
|
||||||
|
}
|
||||||
|
properties.AppendChild(paragraphMarkRunProperties);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
protected override void CreateWord(WordInfo info)
|
||||||
|
{
|
||||||
|
_wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document);
|
||||||
|
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
|
||||||
|
mainPart.Document = new Document();
|
||||||
|
_docBody = mainPart.Document.AppendChild(new Body());
|
||||||
|
}
|
||||||
|
protected override void CreateParagraph(WordParagraph paragraph)
|
||||||
|
{
|
||||||
|
if (_docBody == null || paragraph == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var docParagraph = new Paragraph();
|
||||||
|
|
||||||
|
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
|
||||||
|
foreach (var run in paragraph.Texts)
|
||||||
|
{
|
||||||
|
var docRun = new Run();
|
||||||
|
var properties = new RunProperties();
|
||||||
|
properties.AppendChild(new FontSize { Val = run.Item2.Size });
|
||||||
|
if (run.Item2.Bold)
|
||||||
|
{
|
||||||
|
properties.AppendChild(new Bold());
|
||||||
|
}
|
||||||
|
docRun.AppendChild(properties);
|
||||||
|
docRun.AppendChild(new Text
|
||||||
|
{
|
||||||
|
Text = run.Item1,
|
||||||
|
Space = SpaceProcessingModeValues.Preserve
|
||||||
|
});
|
||||||
|
docParagraph.AppendChild(docRun);
|
||||||
|
}
|
||||||
|
_docBody.AppendChild(docParagraph);
|
||||||
|
}
|
||||||
|
protected override void SaveWord(WordInfo info)
|
||||||
|
{
|
||||||
|
if (_docBody == null || _wordDocument == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_docBody.AppendChild(CreateSectionProperties());
|
||||||
|
_wordDocument.MainDocumentPart!.Document.Save();
|
||||||
|
_wordDocument.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,4 +17,8 @@
|
|||||||
<ProjectReference Include="..\CarServiceDatabase\CarServiceDatabase.csproj" />
|
<ProjectReference Include="..\CarServiceDatabase\CarServiceDatabase.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Files\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using CarServiceContracts.BindingModels;
|
using CarServiceContracts.BindingModels;
|
||||||
using CarServiceContracts.BusinessLogicsContracts;
|
using CarServiceContracts.BusinessLogicsContracts;
|
||||||
using CarServiceWebApp.Models;
|
using CarServiceWebApp.Models;
|
||||||
|
using log4net;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace CarServiceWebApp.Controllers
|
namespace CarServiceWebApp.Controllers
|
||||||
@ -75,5 +76,19 @@ namespace CarServiceWebApp.Controllers
|
|||||||
ViewBag.Payments = payments;
|
ViewBag.Payments = payments;
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
public IActionResult SaveToWord()
|
||||||
|
{
|
||||||
|
_reportLogic.SaveComponentsToWordFile(new ReportBindingModel { SelectedWorks = SelectedWorks, FileName = "C:\\Users\\igors\\source\\repos\\ISEbd-21_Melnikov_I.O._CarService\\CarService\\CarServiceWebApp\\Files\\ReportWord.docx" });
|
||||||
|
return Redirect("~/Report/DownLoadWord");
|
||||||
|
}
|
||||||
|
public IActionResult DownLoadWord()
|
||||||
|
{
|
||||||
|
string filePath = "C:\\Users\\igors\\source\\repos\\ISEbd-21_Melnikov_I.O._CarService\\CarService\\CarServiceWebApp\\Files\\ReportWord.docx";
|
||||||
|
string fileName = "Отчет.docx";
|
||||||
|
|
||||||
|
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
|
||||||
|
|
||||||
|
return File(fileBytes, "application/force-download", fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
CarService/CarServiceWebApp/Files/ReportWord.docx
Normal file
BIN
CarService/CarServiceWebApp/Files/ReportWord.docx
Normal file
Binary file not shown.
@ -1,3 +1,5 @@
|
|||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage;
|
||||||
|
using BlacksmithWorkshopBusinessLogic.OfficePackage.Implements;
|
||||||
using CarServiceBusinessLogic.BusinessLogics;
|
using CarServiceBusinessLogic.BusinessLogics;
|
||||||
using CarServiceContracts.BusinessLogicsContracts;
|
using CarServiceContracts.BusinessLogicsContracts;
|
||||||
using CarServiceContracts.StorageContracts;
|
using CarServiceContracts.StorageContracts;
|
||||||
@ -25,6 +27,8 @@ builder.Services.AddTransient<IWorkInRequestStorage, WorkInRequestStorage>();
|
|||||||
builder.Services.AddTransient<IWorkPaymentStorage, WorkPaymentStorage>();
|
builder.Services.AddTransient<IWorkPaymentStorage, WorkPaymentStorage>();
|
||||||
builder.Services.AddTransient<IReportLogic, ReportLogic>();
|
builder.Services.AddTransient<IReportLogic, ReportLogic>();
|
||||||
|
|
||||||
|
builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>();
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
@ -43,4 +43,6 @@
|
|||||||
<p>Заявок нет</p>
|
<p>Заявок нет</p>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<div><center><a asp-controller="Report" asp-action="SaveToWord" class="btn btn-primary">Сохранить в ворд</a></center></div>
|
||||||
|
<div><center><a asp-controller="Report" asp-action="SaveToExcel" class="btn btn-primary">Сохранить в эксель</a></center></div>
|
||||||
</div>
|
</div>
|
Loading…
x
Reference in New Issue
Block a user