From afef650b263816e86ff9dcac0ae6d1abbe9cd1ea Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 8 Mar 2023 01:29:57 +0100 Subject: [PATCH] Razor Templates --- WGneu/Documents/BusinessDocument.cshtml | 18 ++ WGneu/Documents/BusinessDocument.cshtml.cs | 24 ++ WGneu/Documents/BusinessLetter.cshtml | 8 + WGneu/Documents/BusinessLetter.cshtml.cs | 14 ++ WGneu/Documents/Document.cshtml | 44 ++++ WGneu/Documents/Document.cshtml.cs | 52 ++++ WGneu/Documents/Pdf.cs | 17 ++ WGneu/Documents/Template.cs | 12 +- WGneu/Documents/TestTemplate.cshtml | 249 -------------------- WGneu/Documents/TestTemplateModel.cshtml.cs | 19 -- WGneu/Documents/style.css | 176 ++++++++++++++ 11 files changed, 355 insertions(+), 278 deletions(-) create mode 100644 WGneu/Documents/BusinessDocument.cshtml create mode 100644 WGneu/Documents/BusinessDocument.cshtml.cs create mode 100644 WGneu/Documents/BusinessLetter.cshtml create mode 100644 WGneu/Documents/BusinessLetter.cshtml.cs create mode 100644 WGneu/Documents/Document.cshtml create mode 100644 WGneu/Documents/Document.cshtml.cs delete mode 100644 WGneu/Documents/TestTemplate.cshtml delete mode 100644 WGneu/Documents/TestTemplateModel.cshtml.cs create mode 100644 WGneu/Documents/style.css diff --git a/WGneu/Documents/BusinessDocument.cshtml b/WGneu/Documents/BusinessDocument.cshtml new file mode 100644 index 0000000..ac7b169 --- /dev/null +++ b/WGneu/Documents/BusinessDocument.cshtml @@ -0,0 +1,18 @@ +@using RazorLight +@inherits TemplatePage +@model WGneu.Documents.BusinessDocument +@{ Layout = "Document"; } + +
+
+
+
WG Matzen | Schloßstraße 6 | 2243 Matzen
+
E Österreichische Post AG Eco Brief
+
+
@Model.Address
+
+ +
+
+ @RenderBody() +
diff --git a/WGneu/Documents/BusinessDocument.cshtml.cs b/WGneu/Documents/BusinessDocument.cshtml.cs new file mode 100644 index 0000000..322b5d7 --- /dev/null +++ b/WGneu/Documents/BusinessDocument.cshtml.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WGneu.Models; + +namespace WGneu.Documents { + public class BusinessDocument : Document { + + public BusinessDocument(string title, Member m) : base(title) { + Member = m; + } + + public Member Member { get; set; } + + public string Address { + get { + // TODO Name/Rechnungsadresse + return $"{Member.GivenName} {Member.FamilyName}\n{Member.Address}"; + } + } + } +} diff --git a/WGneu/Documents/BusinessLetter.cshtml b/WGneu/Documents/BusinessLetter.cshtml new file mode 100644 index 0000000..760eccd --- /dev/null +++ b/WGneu/Documents/BusinessLetter.cshtml @@ -0,0 +1,8 @@ +@using RazorLight +@inherits TemplatePage +@model WGneu.Documents.BusinessLetter +@{ Layout = "BusinessDocument"; } + +

Sehr geehrtes Mitglied,

+

nein.

+

Mit freundlichen Grüßen
Ihre Winzergenossenschaft

diff --git a/WGneu/Documents/BusinessLetter.cshtml.cs b/WGneu/Documents/BusinessLetter.cshtml.cs new file mode 100644 index 0000000..6a9ea3d --- /dev/null +++ b/WGneu/Documents/BusinessLetter.cshtml.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WGneu.Models; + +namespace WGneu.Documents { + public class BusinessLetter : BusinessDocument { + public BusinessLetter(string title, Member m) : base(title, m) { + + } + } +} diff --git a/WGneu/Documents/Document.cshtml b/WGneu/Documents/Document.cshtml new file mode 100644 index 0000000..0521e05 --- /dev/null +++ b/WGneu/Documents/Document.cshtml @@ -0,0 +1,44 @@ +@using RazorLight +@inherits TemplatePage +@model WGneu.Documents.Document + + + + + @Model.Title + + + + + + + +
+
+
+
@Model.Header
+ +
+
+ @RenderBody() +
+ + diff --git a/WGneu/Documents/Document.cshtml.cs b/WGneu/Documents/Document.cshtml.cs new file mode 100644 index 0000000..e0a1237 --- /dev/null +++ b/WGneu/Documents/Document.cshtml.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace WGneu.Documents { + public class Document { + + public Document(string title) { + Title = title; + Header = "Winzergenossenschaft Matzen"; + Footer = "Winzergenossenschaft für Matzen und Umgebung reg. Gen.m.b.H."; + Date = DateTime.Today; + } + + public string Title { get; set; } + + public string Header { get; set; } + + public string Footer { get; set; } + + public string FullDateString { + get { + return Date.ToString("dddd, d. MMMM yyyy"); + } + } + + public DateTime Date { get; set; } + + private async Task Render() { + if (this is BusinessLetter bl) { + return await Pdf.CompileRenderAsync("BusinessLetter.cshtml", bl); + } else if (this is BusinessDocument bd) { + return await Pdf.CompileRenderAsync("BusinessDocument.cshtml", bd); + } else { + return await Pdf.CompileRenderAsync("Document.cshtml", this); + } + } + + private async Task SaveHtml() { + await File.WriteAllTextAsync("razor_test.html", await Render()); + return ""; + } + + public async Task Save() { + await SaveHtml(); + return ""; + } + } +} diff --git a/WGneu/Documents/Pdf.cs b/WGneu/Documents/Pdf.cs index 178a571..5151698 100644 --- a/WGneu/Documents/Pdf.cs +++ b/WGneu/Documents/Pdf.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using PdfSharp.Pdf.IO; using PuppeteerSharp; using PuppeteerSharp.Media; +using RazorLight; using WGneu.Windows; namespace WGneu.Documents { @@ -16,9 +17,11 @@ namespace WGneu.Documents { private static readonly string CHROMIUM = @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"; private static IBrowser? _Browser = null; + private static RazorLightEngine? _Engine = null; public static void Init() { var b = Browser; + var e = Engine; } private static IBrowser Browser { @@ -31,6 +34,16 @@ namespace WGneu.Documents { } } + private static RazorLightEngine Engine { + get { + _Engine ??= new RazorLightEngineBuilder() + .UseFileSystemProject(@"C:\Users\Lorenz\source\repos\WGneu\WGneu\Documents") + .UseMemoryCachingProvider() + .Build(); + return _Engine; + } + } + public static async Task Convert(string path_html, string path_pdf) { using var page = await Browser.NewPageAsync(); await page.GoToAsync("file://" + path_html); @@ -59,5 +72,9 @@ namespace WGneu.Documents { var w = new DocumentViewerWindow(title, path); w.Show(); } + + public static async Task CompileRenderAsync(string key, object model) { + return await Engine.CompileRenderAsync(key, model); + } } } diff --git a/WGneu/Documents/Template.cs b/WGneu/Documents/Template.cs index d22b0c4..f0ffb7a 100644 --- a/WGneu/Documents/Template.cs +++ b/WGneu/Documents/Template.cs @@ -20,16 +20,8 @@ namespace WGneu.Documents { } public static async void Generate(WgContext c) { - var engine = new RazorLightEngineBuilder() - .UseFileSystemProject(@"C:\Users\tom\source\repos\wgneu-cs\WGneu\Documents") - .UseMemoryCachingProvider() - .Build(); - - var model = new TestTemplateModel(c); - - string result = await engine.CompileRenderAsync("TestTemplate.cshtml", model); - - await File.WriteAllTextAsync(ROOT + "razor_test.html", result); + var letter = new BusinessLetter("Test Dokument", c.Members.First()); + var pdf_path = await letter.Save(); } } } diff --git a/WGneu/Documents/TestTemplate.cshtml b/WGneu/Documents/TestTemplate.cshtml deleted file mode 100644 index c59b0a8..0000000 --- a/WGneu/Documents/TestTemplate.cshtml +++ /dev/null @@ -1,249 +0,0 @@ -@using RazorLight -@inherits TemplatePage -@model IQueryable - - - - - %SUBJECT% - - - - - - -
-
-
-
-

Winzergenossenschaft Matzen

-
- -
-
-
-
-
-
WG Matzen | Schloßstraße 6 | 2243 Matzen
-
E Österreichische Post AG Eco Brief
-
-
Maximilian Mustermann - Musterstraße 123 - 2222 Musterort - Österreich
-
- -
-
-
Matzen, am 04.03.2023
-

%SUBJECT%

-

Sehr geehrtes Mitglied,

- -

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

-

Ich bin ein langer Paragraph.

- - @foreach (var country in Model.Countries) { -

Land:

-

@Raw(country.Name)

-

@country.Alpha2

-

@country.Alpha3

- } - - - -

- Mit freundlichen Grüßen
- Ihre Winzergenossenschaft Matzen -

-
-
- - diff --git a/WGneu/Documents/TestTemplateModel.cshtml.cs b/WGneu/Documents/TestTemplateModel.cshtml.cs deleted file mode 100644 index a033d85..0000000 --- a/WGneu/Documents/TestTemplateModel.cshtml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WGneu.Models; - -namespace WGneu.Documents { - public class TestTemplateModel { - - public IQueryable Countries { get; set; } - - public TestTemplateModel(WgContext c) { - Countries = c.Countries; - } - - } -} diff --git a/WGneu/Documents/style.css b/WGneu/Documents/style.css new file mode 100644 index 0000000..7e09e11 --- /dev/null +++ b/WGneu/Documents/style.css @@ -0,0 +1,176 @@ + +:root { + font-family: "Times New Roman", serif; + line-height: 1; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; +} + +.m1, .m2, .m3 { + height: 0; + width: 1cm; + position: fixed; + left: 0; + border-top: 1pt solid black; +} + +.m1 {top: 105mm;} +.m2 {top: 148.5mm;} +.m3 {top: 210mm;} + +header { + height: 45mm; + padding: 5mm; + position: absolute; + top: -25mm; + left: 0; + right: 0; + text-align: center; +} +.spacing {height: 20mm;} +.info-wrapper { + width: 100%; + height:45mm; + margin: 0 0 8.46mm 0; + position: relative; +} + +.address-wrapper { + height: 45mm; + width: 85mm; + margin: 0; + padding: 5mm; + position: absolute; + left: 20mm; + top: 0; + display: flex; + flex-direction: column; + justify-content: flex-end; +} + +.address-wrapper .sender { + flex: 17.7mm 1 1; + font-size: 8pt; + display: flex; + flex-direction: column; + justify-content: flex-end; + padding-bottom: 2mm; +} + +address { + flex: 27.3mm 1 1; + white-space: pre-line; + font-size: 12pt; + font-style: normal; +} + +aside { + height: 40mm; + width: 75mm; + margin: 0; + position: absolute; + left: 125mm; + top: 5mm; +} + +main { + margin: 8.46mm 20mm 4.23mm 25mm; +} + +main :first-child { + margin-top: 0; +} + +main h1, main p { + font-size: 12pt; + margin: 1em 0; + text-align: justify; + widows: 3; + orphans: 3; +} + +main .date { + margin-bottom: 2em; + text-align: right; +} + +main h1 { + margin-bottom: 2em; +} + +.footer-wrapper { + padding: 0 20mm 0 25mm; + position: running(page-footer); + bottom: 0; + left: 0; + right: 0; +} + +.pre-footer { + margin: 4.23mm 0; + font-size: 10pt; + display: flex; +} + +.pre-footer .date, .pre-footer .page { + flex: 100px 1 1; +} + +.pre-footer .date {text-align: left;} +.pre-footer .page {text-align: right;} +.page::after { + content: "Seite 1 von 1"; +} + +footer { + font-size: 10pt; + border-top: 1pt solid black; + height: 25mm; + padding-top: 1mm; + text-align: center; +} + +@page { + size: A4; + margin: 25mm 0 35mm 0; + @bottom-center { + content: element(page-footer); + } +} + +@media screen { + body, header, .footer-wrapper { + width: 210mm; + } + header, .address-wrapper, aside, main { + border: 1px solid lightgray; + } + .m1, .m2, .m3 {display: none;} + header {top: 0;} + .spacing {height: 45mm;} + .main-wrapper { + margin-bottom: 40mm; + } + .footer-wrapper { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + } +} + +@media print { + .page::after { + content: "Seite " counter(page) " von " counter(pages); + } + .footer-wrapper { + display: none; + } +}