diff --git a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Storekeeper/ReportStorekeeperLogic.cs b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Storekeeper/ReportStorekeeperLogic.cs index 3d95e07..15942a6 100644 --- a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Storekeeper/ReportStorekeeperLogic.cs +++ b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Storekeeper/ReportStorekeeperLogic.cs @@ -11,22 +11,26 @@ namespace HardwareShopBusinessLogic.BusinessLogics.Storekeeper { private readonly IComponentStorage _componentStorage; + private readonly IGoodStorage _goodStorage; + private readonly AbstractSaveToExcel _saveToExcel; private readonly AbstractSaveToWord _saveToWord; - public ReportStorekeeperLogic(IComponentStorage componentStorage, AbstractSaveToExcel abstractSaveToExcel, AbstractSaveToWord abstractSaveToWord) + public ReportStorekeeperLogic(IComponentStorage componentStorage, AbstractSaveToExcel abstractSaveToExcel, AbstractSaveToWord abstractSaveToWord, IGoodStorage goodStorage) { _componentStorage = componentStorage; _saveToExcel = abstractSaveToExcel; _saveToWord = abstractSaveToWord; + _goodStorage = goodStorage; } public List GetBuildGood(List goods) { var result = new List(); - foreach (var good in goods) + foreach (var g in goods) { + var good = _goodStorage.GetElement(new() { Id = g.Id })!; var builds = good.GoodComponents //получили сборки и количество компонентов .Select(x => _componentStorage.GetComponentBuilds(new() { Id = x.Key }) @@ -78,16 +82,6 @@ namespace HardwareShopBusinessLogic.BusinessLogics.Storekeeper return result; } - public void SaveBuildGoodToExcelFile(ReportBindingModel model, List goods) - { - _saveToExcel.CreateBuildGoodReport(new ExcelInfo - { - FileName = model.FileName, - Title = "Cписок сборок по выбранным товарам", - BuildGood = GetBuildGood(goods) - }); - } - public byte[] SaveBuildGoodToWordFile(ReportBindingModel model, List goods) { _saveToWord.CreateBuildGoodReport(new WordInfo @@ -102,9 +96,18 @@ namespace HardwareShopBusinessLogic.BusinessLogics.Storekeeper return file; } - byte[] IReportStorekeeperLogic.SaveBuildGoodToExcelFile(ReportBindingModel model, List goods) + public byte[] SaveBuildGoodToExcelFile(ReportBindingModel model, List goods) { - throw new NotImplementedException(); + _saveToExcel.CreateBuildGoodReport(new ExcelInfo + { + FileName = model.FileName, + Title = "Cписок сборок по выбранным товарам", + BuildGood = GetBuildGood(goods) + }); + + byte[] file = File.ReadAllBytes(model.FileName); + File.Delete(model.FileName); + return file; } } } diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs index fecb287..10da8a0 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs @@ -24,7 +24,7 @@ namespace HardwareShopBusinessLogic.OfficePackage MergeCells(new ExcelMergeParameters { CellFromName = "A1", - CellToName = "C1" + CellToName = "B1" }); uint rowIndex = 2; @@ -35,7 +35,7 @@ namespace HardwareShopBusinessLogic.OfficePackage ColumnName = "A", RowIndex = rowIndex, Text = bg.GoodName, - StyleInfo = ExcelStyleInfoType.Text + StyleInfo = ExcelStyleInfoType.TextWithBroder }); rowIndex++; @@ -51,8 +51,6 @@ namespace HardwareShopBusinessLogic.OfficePackage rowIndex++; } - - rowIndex++; } SaveExcel(info); diff --git a/HardwareShop/HardwareShopClientApp/APIClient.cs b/HardwareShop/HardwareShopClientApp/APIClient.cs index f83e062..810244c 100644 --- a/HardwareShop/HardwareShopClientApp/APIClient.cs +++ b/HardwareShop/HardwareShopClientApp/APIClient.cs @@ -46,5 +46,23 @@ namespace HardwareShopStorekeeperApp throw new Exception(result); } } + + public static R? PostRequestWithResult(string requestUrl, T model) + { + var json = JsonConvert.SerializeObject(model); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = _client.PostAsync(requestUrl, data); + + var result = response.Result.Content.ReadAsStringAsync().Result; + if (response.Result.IsSuccessStatusCode) + { + return JsonConvert.DeserializeObject(result); + } + else + { + return default; + } + } } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopClientApp/Controllers/StorekeeperController.cs b/HardwareShop/HardwareShopClientApp/Controllers/StorekeeperController.cs index 39ef02f..c7f00d5 100644 --- a/HardwareShop/HardwareShopClientApp/Controllers/StorekeeperController.cs +++ b/HardwareShop/HardwareShopClientApp/Controllers/StorekeeperController.cs @@ -396,7 +396,7 @@ namespace HardwareShopStorekeeperApp.Controllers } [HttpPost] - public void ListBuilds([FromBody] GoodBindingModel goodModel, [FromQuery] string format, [FromQuery] string filename) + public int[]? ListBuilds([FromBody] GoodBindingModel goodModel, [FromQuery] string format) { if (APIClient.User == null) { @@ -404,13 +404,10 @@ namespace HardwareShopStorekeeperApp.Controllers } if (string.IsNullOrEmpty(format)) { - throw new FormatException($"Неправильный формат файла: {format}"); + throw new FormatException("Неправильный формат файла"); } - if (string.IsNullOrEmpty(filename)) - { - throw new FormatException($"Неправильное название файла: {filename}"); - } - APIClient.PostRequest($"api/report/buildgoodreport?format={format}&filename=${filename}", goodModel); + byte[]? file = APIClient.PostRequestWithResult($"api/report/buildgoodreport?format={format}", goodModel); + return file!.Select(b => (int)b).ToArray(); } public IActionResult Report() diff --git a/HardwareShop/HardwareShopClientApp/Views/Storekeeper/ListBuilds.cshtml b/HardwareShop/HardwareShopClientApp/Views/Storekeeper/ListBuilds.cshtml index c9fac2e..cfc8c7b 100644 --- a/HardwareShop/HardwareShopClientApp/Views/Storekeeper/ListBuilds.cshtml +++ b/HardwareShop/HardwareShopClientApp/Views/Storekeeper/ListBuilds.cshtml @@ -23,10 +23,6 @@ -
- - -
@@ -59,7 +55,6 @@ const resultTable = document.getElementById("result"); const saveDocBtn = document.getElementById("savedoc"); const saveExcelBtn = document.getElementById("saveexcel"); - const filename = document.getElementById("filename"); submitGoodBtn.addEventListener("click", () => { console.log('try to add good') @@ -88,32 +83,53 @@ }) saveDocBtn.addEventListener("click", async () => { - send('doc') + send('docx') }) saveExcelBtn.addEventListener("click", async () => { - send('excel') + send('xlsx') }) function send(format) { console.log(`try to save in ${format} format`) - if (list.length == 0 || !filename.value || filename.value == '') { - alert('operation failed. goods or filename are empty') + if (list.length == 0) { + alert('operation failed. goods are empty') return } $.ajax({ - url: `/Storekeeper/ListBuilds?format=${format}&filename=${filename.value}`, + url: `/Storekeeper/ListBuilds?format=${format}`, type: 'POST', contentType: 'application/json', data: JSON.stringify({ "Goods" : list }) - }).done(() => { - //let byteArray = new Uint8Array(file); + }).done((file) => { + let byteArray = new Uint8Array(file); + saveFile(byteArray, format); }) .fail(function(xhr, textStatus, errorThrown) { alert(xhr.responseText); }) } + async function saveFile(bytes, format) { + if (window.showSaveFilePicker) { + const opts = { + suggestedName: `listbuilds.${format}`, + types: [{ + description: `${format} file`, + accept: + { + [`text/${format}`]: [`.${format}`] + }, + }], + }; + const handle = await showSaveFilePicker(opts); + const writable = await handle.createWritable(); + await writable.write(bytes); + writable.close(); + alert('done') + } + } + function reloadTable() { resultTable.innerHTML = '' let count = 0; diff --git a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs index 4083037..9d95c6d 100644 --- a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs +++ b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs @@ -20,21 +20,23 @@ namespace HardwareShopRestApi.Controllers } [HttpPost] - public void BuildGoodReport(GoodBindingModel model, string format, string filename) + public byte[] BuildGoodReport(GoodBindingModel model, string format) { try { + byte[] file; switch (format) { - case "doc": - _reportStorekeeperLogic.SaveBuildGoodToWordFile(new ReportBindingModel { FileName = filename }, model.Goods); + case "docx": + file = _reportStorekeeperLogic.SaveBuildGoodToWordFile(new ReportBindingModel { FileName = "temp.docx" }, model.Goods); break; - case "excel": - _reportStorekeeperLogic.SaveBuildGoodToExcelFile(new ReportBindingModel { FileName = filename }, model.Goods); + case "xlsx": + file = _reportStorekeeperLogic.SaveBuildGoodToExcelFile(new ReportBindingModel { FileName = "temp.xlsx" }, model.Goods); break; default: throw new FormatException("Неправильный формат файла"); } + return file; } catch (Exception ex) { diff --git a/HardwareShop/HardwareShopRestApi/qwe.xlsx b/HardwareShop/HardwareShopRestApi/qwe.xlsx new file mode 100644 index 0000000..6340319 Binary files /dev/null and b/HardwareShop/HardwareShopRestApi/qwe.xlsx differ