diff --git a/src/WorkFlowCheck.API/Controllers/CheckListController.cs b/src/WorkFlowCheck.API/Controllers/CheckListController.cs index 6436d79..e219757 100644 --- a/src/WorkFlowCheck.API/Controllers/CheckListController.cs +++ b/src/WorkFlowCheck.API/Controllers/CheckListController.cs @@ -47,7 +47,7 @@ namespace WorkFlowCheck.API.Controllers IsSuccess = true, }; var checkListHeader = await _checkListService.GetCheckListHeaderAsync(id); - var response = _checkListService.CreatePDF(id); + var response = await _checkListService.CreatePDF(id); if (response != null) { diff --git a/src/WorkFlowCheck.API/Pdf/CheckList_Template_V1.docx b/src/WorkFlowCheck.API/Pdf/CheckList_Template_V1.docx index b0a99cf..914e80a 100644 Binary files a/src/WorkFlowCheck.API/Pdf/CheckList_Template_V1.docx and b/src/WorkFlowCheck.API/Pdf/CheckList_Template_V1.docx differ diff --git a/src/WorkFlowCheck.BL/DocumentGenerator/DokumentumGenerator.cs b/src/WorkFlowCheck.BL/DocumentGenerator/DokumentumGenerator.cs index 42ea204..dc2837c 100644 --- a/src/WorkFlowCheck.BL/DocumentGenerator/DokumentumGenerator.cs +++ b/src/WorkFlowCheck.BL/DocumentGenerator/DokumentumGenerator.cs @@ -1,35 +1,59 @@ -using DevExpress.XtraRichEdit; +using System.Diagnostics; namespace WorkFlowCheck.BL.DocumentGenerator { public class DokumentumGenerator { - public static byte[] DocxToPdf(byte[] wordBytes) + public static byte[] DocxToPdfL(byte[] wordBytes) { - using (MemoryStream inputStream = new MemoryStream(wordBytes)) - using (MemoryStream outputStream = new MemoryStream()) + string pdfDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Pdf"); + string fileName = Guid.NewGuid().ToString(); + + string tempWordPath = Path.Combine(pdfDirectory, fileName + ".docx"); + string tempPdfPath = Path.Combine(pdfDirectory, fileName + ".pdf"); + + try { - try + // Word fájl mentése ideiglenes fájlba + File.WriteAllBytes(tempWordPath, wordBytes); + + // LibreOffice parancssori konverzió + ProcessStartInfo startInfo = new ProcessStartInfo { - // RichEditDocumentServer használata a konverzióhoz - using (RichEditDocumentServer wordProcessor = new RichEditDocumentServer()) - { - // Dokumentum betöltése a byte tömbből - wordProcessor.LoadDocument(inputStream, DevExpress.XtraRichEdit.DocumentFormat.OpenXml); + FileName = "e:\\LibreOffice\\program\\soffice", // LibreOffice parancs + Arguments = $"--headless --convert-to pdf \"{tempWordPath}\" --outdir \"{pdfDirectory}", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; - // PDF formátumba mentés a memóriafolyamba - wordProcessor.ExportToPdf(outputStream); - - // PDF byte tömb visszaadása - return outputStream.ToArray(); - } + using (Process process = Process.Start(startInfo)) + { + process.WaitForExit(); } - catch (Exception ex) + + // Ellenőrzés, hogy létrejött-e a PDF + if (File.Exists(tempPdfPath)) { - Console.WriteLine("Hiba a konverzió során: " + ex.Message); - return new byte[0]; + byte[] pdfBytes = File.ReadAllBytes(tempPdfPath); + + // Ideiglenes fájlok törlése + File.Delete(tempWordPath); + File.Delete(tempPdfPath); + + return pdfBytes; + } + else + { + throw new Exception("PDF konverzió sikertelen."); } } + catch (Exception ex) + { + Console.WriteLine("Hiba a PDF konverzió során: " + ex.Message); + return null; + } } + } } diff --git a/src/WorkFlowCheck.BL/DocumentGenerator/SablonGenerator.cs b/src/WorkFlowCheck.BL/DocumentGenerator/SablonGenerator.cs index 25b339f..e8d8e14 100644 --- a/src/WorkFlowCheck.BL/DocumentGenerator/SablonGenerator.cs +++ b/src/WorkFlowCheck.BL/DocumentGenerator/SablonGenerator.cs @@ -424,7 +424,7 @@ namespace WorkFlowCheck.BL.DocumentGenerator /// sorok és benne az egyes cellák tartalma /// első (nem fejléc) sorában lévő kulcs, ez alapján azonosítjuk be a táblázatot /// ha igaz, a táblázat összes meglévő sorát törli - public void SetTable(List> rowsAndCells, string keyInRow, bool deleteEmptyRow = false) + public void SetTable_Old(List> rowsAndCells, string keyInRow, bool deleteEmptyRow = false) { Body bod = Doc.MainDocumentPart.Document.Body; var table = bod.Descendants().Where(tbl => tbl.InnerText.Contains(keyInRow)).FirstOrDefault(); @@ -458,6 +458,79 @@ namespace WorkFlowCheck.BL.DocumentGenerator } } } + public void SetTable(List> rowsAndCells, string keyInRow, bool deleteEmptyRow = false) + { + Body bod = Doc.MainDocumentPart.Document.Body; + var table = bod.Descendants
().Where(tbl => tbl.InnerText.Contains(keyInRow)).FirstOrDefault(); + if (table != null) + { + TableRow formatRow = null; + + // Megkeressük az első sort és elmentjük a formázást + if (deleteEmptyRow) + { + var firstRow = table.ChildElements.OfType().FirstOrDefault(); + if (firstRow != null) + { + formatRow = (TableRow)firstRow.CloneNode(true); // Az első sor másolása formázással + var deletedRows = table.ChildElements.OfType().ToList(); + foreach (var item in deletedRows) + table.RemoveChild(item); + } + } + else + { + var deletedRow = table.ChildElements.OfType().LastOrDefault(); + if (deletedRow != null) + { + formatRow = (TableRow)deletedRow.CloneNode(true); // Az utolsó sor másolása formázással + table.RemoveChild(deletedRow); + } + } + + // Új sorok beszúrása a mentett formázással + foreach (var row in rowsAndCells) + { + List cells = new List(); + + for (int i = 0; i < row.Count; i++) + { + var cellText = row[i].Replace("#", ""); + + // Ha van formázási minta, alkalmazzuk + TableCell newCell; + if (formatRow != null && i < formatRow.Elements().Count()) + { + var formatCell = formatRow.Elements().ElementAt(i); + var clonedCell = (TableCell)formatCell.CloneNode(true); + var para = clonedCell.Descendants().FirstOrDefault(); + + // Ha van beágyazott szöveg, frissítjük a tartalmát + if (para != null) + { + var run = para.Descendants().FirstOrDefault(); + if (run != null) + { + run.RemoveAllChildren(); + run.AppendChild(new Text(cellText)); + } + } + + newCell = clonedCell; + } + else + { + // Alapértelmezett cella, ha nincs formázási minta + newCell = new TableCell(new Paragraph(new Run(new Text(cellText)))); + } + + cells.Add(newCell); + } + + table.Append(new TableRow(cells)); + } + } + } public byte[] CloseAndGetDocument() { diff --git a/src/WorkFlowCheck.BL/Services/CheckListService.cs b/src/WorkFlowCheck.BL/Services/CheckListService.cs index c3c8137..773bf38 100644 --- a/src/WorkFlowCheck.BL/Services/CheckListService.cs +++ b/src/WorkFlowCheck.BL/Services/CheckListService.cs @@ -1,4 +1,5 @@ using AutoMapper; +using DocumentFormat.OpenXml.Office.CustomUI; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using Serilog; @@ -424,18 +425,40 @@ namespace WorkFlowCheck.BL.Services return retVal; } - public byte[] CreatePDF(int checkListHeaderId) + public async Task CreatePDF(int checkListHeaderId) { try { + var checkListHeader = await this.GetCheckListHeaderAsync(checkListHeaderId); + string pdfDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Pdf"); byte[] byteArray = File.ReadAllBytes(Path.Combine(pdfDirectory, "CheckList_Template_V1.docx")); SablonGenerator gen = new SablonGenerator(byteArray); + if (checkListHeader.CheckListRowDTO != null && checkListHeader.CheckListRowDTO.Count > 0) + { + var elements = new List>(); + foreach (var item in checkListHeader.CheckListRowDTO) + { + if (item.CheckListTemplateRowDTO != null) + { + var cells = new List + { + $"{item.CheckListTemplateRowDTO.RowIndex.ToString()}.", + item.CheckListTemplateRowDTO.OperationDescription, + item.Answer + }; + elements.Add(cells); + } + } + gen.SetTable(elements, "#rowindex"); + } + + byte[] content = gen.CloseAndGetDocument(); - return DokumentumGenerator.DocxToPdf(content); + return DokumentumGenerator.DocxToPdfL(content); } catch (Exception ex) { diff --git a/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs b/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs index 98505a9..892899e 100644 --- a/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs +++ b/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs @@ -23,6 +23,6 @@ namespace WorkFlowCheck.BL.Services.Interfaces Task UpdateCheckListRowAsync(CheckListRowDTO checkListRowDTO); - byte[] CreatePDF(int checkListHeaderId); + Task CreatePDF(int checkListHeaderId); } } diff --git a/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj b/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj index dd1a6a6..9125e70 100644 --- a/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj +++ b/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj @@ -8,7 +8,6 @@ - diff --git a/src/WorkFlowCheck.Web/wwwroot/js/site.js b/src/WorkFlowCheck.Web/wwwroot/js/site.js index 815ecc3..1ee1faf 100644 --- a/src/WorkFlowCheck.Web/wwwroot/js/site.js +++ b/src/WorkFlowCheck.Web/wwwroot/js/site.js @@ -194,7 +194,31 @@ function renderAnswerType(data) { } function renderAnswerPhoto(data, row) { if (row.checkListTemplateRowDTO.answerType === 'P') { - return `Image` + return `
Image
`; } - return data; + if (row.checkListTemplateRowDTO.answerType === 'SI-N' && data === 'Igen') { + return '
I
'; + } + if (row.checkListTemplateRowDTO.answerType === 'SI-N' && data === 'Nem') { + return '
N
'; + } + if (row.checkListTemplateRowDTO.answerType === 'I-SN' && data === 'Igen') { + return '
I
'; + } + if (row.checkListTemplateRowDTO.answerType === 'I-SN' && data === 'Nem') { + return '
N
'; + } + if (row.checkListTemplateRowDTO.answerType === 'PI-N' && data === 'Igen') { + return '
I
'; + } + if (row.checkListTemplateRowDTO.answerType === 'PI-N' && data === 'Nem') { + return '
N
'; + } + if (row.checkListTemplateRowDTO.answerType === 'I-PN' && data === 'Igen') { + return '
I
'; + } + if (row.checkListTemplateRowDTO.answerType === 'I-PN' && data === 'Nem') { + return '
N
'; + } + return `
${data}
`; }