Commit 47ab6f5f authored by Nuno Alves's avatar Nuno Alves
Browse files

set italic style for specific expressions; change report section header data...

set italic style for specific expressions; change report section header data type and adjust code accordingly;
parent bdf84c3f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
In diesem Repository geht es um die Generierung von PDF-Dokumenten über einen Microservice via Web API. Eine WebUi wird zusätzlich zum Testen von Anfragen mit Dateneingabe bereitgestellt. In diesem Repository geht es um die Generierung von PDF-Dokumenten über einen Microservice via Web API. Eine WebUi wird zusätzlich zum Testen von Anfragen mit Dateneingabe bereitgestellt.
Grundsätzlich werden befüllte Datenmodelle über einen Webservice an einen PDFGenerator Microservice gesendet, der dafür sorgt, PDF-Dateien aus den empfangengen Datenmodellen zu erzeugen. Vom Webserver wird entweder ein Evaluationsbericht oder ein Factsheet je nach aufgerufenem URI generiert und das entsprechende PDF-Dokument als byte Array zurückgegeben. Grundsätzlich werden befüllte Datenmodelle über einen Webservice an einen PDFGenerator Microservice gesendet, der dafür sorgt, PDF-Dateien aus den empfangengen Datenmodellen zu erzeugen. Vom Webserver wird entweder ein Evaluationsbericht oder ein Fac Sheet je nach aufgerufenem URI generiert und das entsprechende PDF-Dokument als byte Array zurückgegeben.
Der Microservice-Server Web API widmet sich der Generierung von Pdf-Dokumenten anhand der verwendeten _iText7_-Bibliothek. _iText_ ist eine freie Programmbibliothek zur Erzeugung und Bearbeitung von PDF-Dateien mittels der Programmiersprachen _Java_ oder _C#_, deren Software unter der [GNU Affero General Public License](https://de.wikipedia.org/wiki/GNU_Affero_General_Public_License) (AGPL) vertrieben wird. Der Microservice-Server Web API widmet sich der Generierung von Pdf-Dokumenten anhand der verwendeten _iText7_-Bibliothek. _iText_ ist eine freie Programmbibliothek zur Erzeugung und Bearbeitung von PDF-Dateien mittels der Programmiersprachen _Java_ oder _C#_, deren Software unter der [GNU Affero General Public License](https://de.wikipedia.org/wiki/GNU_Affero_General_Public_License) (AGPL) vertrieben wird.
...@@ -31,14 +31,35 @@ public class EvaluationReport ...@@ -31,14 +31,35 @@ public class EvaluationReport
Dieses Datenmodell befindet sich unter `pdf-generator\Models\EvaluationReport.cs`. Dieses Datenmodell befindet sich unter `pdf-generator\Models\EvaluationReport.cs`.
### Datenmodell für das Factsheet ### Datenmodell für das Fact Sheet
Text Zu den Bestandteilen eines Fact Sheet zählen das Deckblatt (Cover), eine Kopf- und Fußzeile (Header, Footer) sowie eine Menge von Kapiteln, in denen mehrere Reports jeweils dargestellt werden. Außerdem gibt es eine "Keine Daten vorhanden"-Meldung, welche falls zutreffend in jedem Kapitel anwendbar ist:
```csharp
public class FactSheet
{
public PDFHeaderFooter Header { get; set; }
public PDFHeaderFooter Footer { get; set; }
public PDFCover Cover { get; set; }
public PDFChapter[] Chapters { get; set; }
public Headline NoDataAvailable { get; set; }
}
```
Dieses Datenmodell befindet sich unter `pdf-generator\Models\FactSheet.cs`.
## Generierung des Evaluationsberichts ## Generierung des Evaluationsberichts
Als Erstes wird ein _EvaluationReportRenderer_ mit dem EvaluationReport-Inhalt aus dem Request-Body instantiiert, der für die Erstellung des PDF-Dokuments mit dem zugehörigen Inhalt zuständig ist. Als Erstes wird in _EvaluationReportController_ ein _EvaluationReportRenderer_ mit dem EvaluationReport-Inhalt aus dem Request-Body instantiiert, der für die Erstellung des PDF-Dokuments mit dem zugehörigen Inhalt zuständig ist.
Mittels _RenderSections_ wird danach jeder einzelner Abschnitt ins Dokument geschrieben. Da das Inhaltsverzeichnis als letzter Abschnitt gerendert wird und direkt hinter dem Deckblatt liegen soll, werden die Seiten anschließend umsortiert (_MoveTocToFront_). Als Nächtes wird eine Kopfzeile fürs ganze Dokument geschrieben (_AddHeader_). Mittels _RenderSections_ wird danach jeder einzelner Abschnitt ins Dokument geschrieben. Da das Inhaltsverzeichnis als letzter Abschnitt gerendert wird und direkt hinter dem Deckblatt liegen soll, werden die Seiten anschließend umsortiert (_MoveTocToFront_). Als Nächtes wird eine Kopfzeile fürs ganze Dokument geschrieben (_AddHeader_).
Zuletzt wird das Dokument als byte-Array zurückgegeben. Zuletzt wird das Dokument als byte-Array zurückgegeben.
## Fact Sheet Generierung
In _FactSheetController_ befindet sich die vom _WebClient_ aufgerufene Methode RenderFactSheet, in welcher der _FactSheetRenderer_ mit dem befüllten Fact Sheet-Datenmodell instanziiert wird, das für dein Einbau jedes Bestandteils durch die Methode _Render_ sorgt. Daraus ergibt sich ein an den Peek-Client zurückgebendes byte Array.
In der Methode _Render_ werden zunächst das Deckblatt (_RenderCover_), gefolgt von dem jeweiligen Kapitel (_RenderChapters_) ins Dokument geschrieben. Anschließend wird dem ganzen Dokument Kopf- und Fußzeile hinzugefügt (_RenderHeaderFooter_).
Zum Schluss wird das Dokument von einem Stream in Array umgewandelt und an den _WebClient_ zurückgesendet.
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using PDFGenerator.Renderers; using PDFGenerator.Renderers;
using EvaluationReportModel = PDFGenerator.Models.EvaluationReport.EvaluationReport;
namespace PDFGenerator.Controllers namespace PDFGenerator.Controllers
{ {
...@@ -8,11 +9,11 @@ namespace PDFGenerator.Controllers ...@@ -8,11 +9,11 @@ namespace PDFGenerator.Controllers
[Route("[controller]")] [Route("[controller]")]
public class EvaluationReportController : ControllerBase public class EvaluationReportController : ControllerBase
{ {
private readonly ILogger<EvaluationReportController> _logger; private ILogger<EvaluationReportController> Logger { get; }
public EvaluationReportController(ILogger<EvaluationReportController> logger) public EvaluationReportController(ILogger<EvaluationReportController> logger)
{ {
_logger = logger; Logger = logger;
} }
/// <summary> /// <summary>
...@@ -32,14 +33,14 @@ namespace PDFGenerator.Controllers ...@@ -32,14 +33,14 @@ namespace PDFGenerator.Controllers
/// <returns>PDF document as byte array.</returns> /// <returns>PDF document as byte array.</returns>
[HttpPost("RenderReport")] [HttpPost("RenderReport")]
[RequestSizeLimit(100000000)] [RequestSizeLimit(100000000)]
public byte[] RenderReport([FromBody] PDFGenerator.Models.EvaluationReport evaluationReport) public byte[] RenderReport([FromBody] EvaluationReportModel evaluationReport)
{ {
_logger.Log(LogLevel.Debug, "Start rendering pdf report."); Logger.Log(LogLevel.Debug, "Start rendering pdf report.");
IRenderer Renderer = new EvaluationReportRenderer(evaluationReport); IRenderer Renderer = new EvaluationReportRenderer(evaluationReport);
byte[] file = Renderer.Render(); byte[] file = Renderer.Render();
_logger.Log(LogLevel.Debug, "Finished rendering pdf report."); Logger.Log(LogLevel.Debug, "Finished rendering pdf report.");
return file; return file;
} }
} }
......
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using PDFGenerator.Renderers;
using FactSheetModel = PDFGenerator.Models.FactSheet.FactSheet;
namespace PDFGenerator.Controllers
{
[Route("[controller]")]
[ApiController]
public class FactSheetController : ControllerBase
{
private ILogger<FactSheetController> Logger { get; }
public FactSheetController(ILogger<FactSheetController> logger)
{
Logger = logger;
}
/// <summary>
/// Say hello!
/// </summary>
/// <returns>"Hello"</returns>
[HttpGet("Hello")]
public string Get()
{
return "Hello";
}
/// <summary>
/// Generates the PDF for a factSheet.
/// </summary>
/// <param name="factSheet">FactSheet for which the PDF should be rendered.</param>
/// <returns>PDF document as byte array.</returns>
[HttpPost("RenderFactSheet")]
[RequestSizeLimit(100000000)]
public byte[] RenderFactSheet([FromBody] FactSheetModel factSheet)
{
Logger.Log(LogLevel.Debug, "Start rendering pdf for the Fact Sheet.");
IRenderer Renderer = new FactSheetRenderer(factSheet);
byte[] file = Renderer.Render();
Logger.Log(LogLevel.Debug, "Finished rendering pdf for the Fact Sheet.");
return file;
}
}
}
using iText.Kernel.Geom;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace PDFGenerator.DocumentStructures
{
public abstract class BaseSection
{
protected Document Document { get; set; }
public BaseSection(Document document)
{
Document = document;
}
/// <summary>
/// Adds page break to document.
/// </summary>
public void AddPageBreak()
{
Document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
/// <summary>
/// Gets default page size.
/// </summary>
/// <returns>The default page size.</returns>
protected PageSize GetPageSize()
{
return Document.GetPdfDocument().GetDefaultPageSize();
}
}
}
...@@ -4,17 +4,19 @@ using iText.Kernel.Pdf.Xobject; ...@@ -4,17 +4,19 @@ using iText.Kernel.Pdf.Xobject;
using iText.Layout; using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport
namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
internal class Appendix : BaseSection internal class Appendix : EvaluationReportBaseSection
{ {
private PDFAppendix PDFAppendix { get; } private PDFAppendix PDFAppendix { get; }
private bool FirstFile { get; set; } private bool FirstFile { get; set; }
......
using iText.Layout; using iText.Layout;
using iText.Layout.Element; using iText.Layout.Element;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class CourseGeneralInformation : BaseSection public class CourseGeneralInformation : EvaluationReportBaseSection
{ {
private PDFCourseGeneralInformation Information { get; } private PDFCourseGeneralInformation Information { get; }
public Dictionary<string, byte[]> CustomUploads { get; private set; } public Dictionary<string, byte[]> CustomUploads { get; private set; }
......
...@@ -2,15 +2,16 @@ using iText.Kernel.Colors; ...@@ -2,15 +2,16 @@ using iText.Kernel.Colors;
using iText.Layout; using iText.Layout;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class CourseInformationTables : BaseSection public class CourseInformationTables : EvaluationReportBaseSection
{ {
private PDFCourseInformationTables Tables { get; } private PDFCourseInformationTables Tables { get; }
public CourseInformationTables(PDFCourseInformationTables tables, Document document, Bookmarks bookmarks, TableOfContents tableOfContents) public CourseInformationTables(PDFCourseInformationTables tables, Document document, Bookmarks bookmarks, TableOfContents tableOfContents)
......
...@@ -3,15 +3,16 @@ using iText.Kernel.Geom; ...@@ -3,15 +3,16 @@ using iText.Kernel.Geom;
using iText.Layout; using iText.Layout;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System; using System;
using static PDFGenerator.Utilities.Conversion; using static PDFGenerator.Utilities.Conversion;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class Cover : BaseSection public class Cover : EvaluationReportBaseSection
{ {
private PDFCover PDFCover { get; } private PDFCover PDFCover { get; }
......
...@@ -5,11 +5,12 @@ using PDFGenerator.Utilities; ...@@ -5,11 +5,12 @@ using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Target = PDFGenerator.Models.CriterionTarget; using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
using Target = PDFGenerator.Models.EvaluationReport.CriterionTarget;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class CriterionTarget : BaseSection public class CriterionTarget : EvaluationReportBaseSection
{ {
private Target Target { get; } private Target Target { get; }
private int SectionIndent { get; } private int SectionIndent { get; }
......
...@@ -6,26 +6,25 @@ using iText.Layout; ...@@ -6,26 +6,25 @@ using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Renderers;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public abstract class BaseSection public abstract class EvaluationReportBaseSection : BaseSection
{ {
protected Document Document { get; set; }
protected PdfOutline RootOutline { get; } protected PdfOutline RootOutline { get; }
protected Bookmarks Bookmarks { get; } protected Bookmarks Bookmarks { get; }
protected TableOfContents TableOfContents { get; } protected TableOfContents TableOfContents { get; }
protected static Text NewLine { get; } = new Text("\n"); protected static Text NewLine { get; } = new Text("\n");
public BaseSection(Document document, Bookmarks bookmarks, TableOfContents tableOfContents) public EvaluationReportBaseSection(Document document, Bookmarks bookmarks, TableOfContents tableOfContents) : base(document)
{ {
Document = document;
Bookmarks = bookmarks; Bookmarks = bookmarks;
TableOfContents = tableOfContents; TableOfContents = tableOfContents;
...@@ -47,15 +46,6 @@ namespace PDFGenerator.EvaluationReport ...@@ -47,15 +46,6 @@ namespace PDFGenerator.EvaluationReport
return Document.GetPdfDocument().GetNumberOfPages(); return Document.GetPdfDocument().GetNumberOfPages();
} }
/// <summary>
/// Gets default page size.
/// </summary>
/// <returns>The default page size.</returns>
protected PageSize GetPageSize()
{
return Document.GetPdfDocument().GetDefaultPageSize();
}
/// <summary> /// <summary>
/// Resizes image to fit page size. /// Resizes image to fit page size.
/// </summary> /// </summary>
...@@ -147,7 +137,7 @@ namespace PDFGenerator.EvaluationReport ...@@ -147,7 +137,7 @@ namespace PDFGenerator.EvaluationReport
/// Adds paragraph above the table. /// Adds paragraph above the table.
/// </summary> /// </summary>
/// <param name="table">The table on which the paragraph is added.</param> /// <param name="table">The table on which the paragraph is added.</param>
/// <param name="text">The paragraphs content.<param> /// <param name="text">The paragraphs content.</param>
/// <param name="header">Flag indicating whether the content is a table header.</param> /// <param name="header">Flag indicating whether the content is a table header.</param>
/// <param name="style">Given style for paragraph.</param> /// <param name="style">Given style for paragraph.</param>
protected void AddParagraphWithLeadingToTable(Table table, string text, bool header, Style style = null) protected void AddParagraphWithLeadingToTable(Table table, string text, bool header, Style style = null)
...@@ -205,14 +195,6 @@ namespace PDFGenerator.EvaluationReport ...@@ -205,14 +195,6 @@ namespace PDFGenerator.EvaluationReport
return "\u0000" + Regex.Replace(text, @"\n", "\n\u0000"); return "\u0000" + Regex.Replace(text, @"\n", "\n\u0000");
} }
/// <summary>
/// Adds page break to document.
/// </summary>
public void AddPageBreak()
{
Document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
/// <summary> /// <summary>
/// Adds scaled image to document. /// Adds scaled image to document.
/// </summary> /// </summary>
......
...@@ -3,14 +3,15 @@ using iText.Layout; ...@@ -3,14 +3,15 @@ using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class EvaluationResults : BaseSection public class EvaluationResults : EvaluationReportBaseSection
{ {
private PDFEvaluationResults Results { get; } private PDFEvaluationResults Results { get; }
public Dictionary<string, byte[]> CustomUploads { get; private set; } public Dictionary<string, byte[]> CustomUploads { get; private set; }
......
...@@ -2,14 +2,15 @@ using iText.Kernel.Colors; ...@@ -2,14 +2,15 @@ using iText.Kernel.Colors;
using iText.Layout; using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using KPIEvaluation = PDFGenerator.Models.KpiEvaluation; using KPIEvaluation = PDFGenerator.Models.EvaluationReport.KpiEvaluation;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class KpiEvaluation : BaseSection public class KpiEvaluation : EvaluationReportBaseSection
{ {
private KPIEvaluation Evaluation { get; } private KPIEvaluation Evaluation { get; }
private Table Table { get; set; } private Table Table { get; set; }
......
...@@ -3,14 +3,15 @@ using iText.Kernel.Pdf.Action; ...@@ -3,14 +3,15 @@ using iText.Kernel.Pdf.Action;
using iText.Layout; using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using Reports = PDFGenerator.Models.KpiEvaluationReports; using Reports = PDFGenerator.Models.EvaluationReport.KpiEvaluationReports;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class KpiEvaluationReports : BaseSection public class KpiEvaluationReports : EvaluationReportBaseSection
{ {
private Reports Reports { get; } private Reports Reports { get; }
private Table Table { get; set; } private Table Table { get; set; }
......
...@@ -3,14 +3,15 @@ using iText.Layout; ...@@ -3,14 +3,15 @@ using iText.Layout;
using iText.Layout.Borders; using iText.Layout.Borders;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Models; using PDFGenerator.Models.EvaluationReport;
using PDFGenerator.Utilities; using PDFGenerator.Utilities;
using System.Linq; using System.Linq;
using static PDFGenerator.Utilities.Globals; using static PDFGenerator.Utilities.Globals;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public class Preface : BaseSection public class Preface : EvaluationReportBaseSection
{ {
private PDFPreface PDFPreface { get; } private PDFPreface PDFPreface { get; }
......
...@@ -5,11 +5,11 @@ using iText.Kernel.Pdf.Canvas.Draw; ...@@ -5,11 +5,11 @@ using iText.Kernel.Pdf.Canvas.Draw;
using iText.Layout; using iText.Layout;
using iText.Layout.Element; using iText.Layout.Element;
using iText.Layout.Properties; using iText.Layout.Properties;
using PDFGenerator.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Styles = PDFGenerator.Utilities.Globals.Constants.EvaluationReport.Styles;
namespace PDFGenerator.EvaluationReport namespace PDFGenerator.DocumentStructures.EvaluationReport
{ {
public struct TocItem public struct TocItem
{ {
......