diff --git a/Elwig/Documents/BusinessDocument.cs b/Elwig/Documents/BusinessDocument.cs index ccd2d94..8901917 100644 --- a/Elwig/Documents/BusinessDocument.cs +++ b/Elwig/Documents/BusinessDocument.cs @@ -2,6 +2,7 @@ using Elwig.Helpers; using Elwig.Models; using Elwig.Models.Entities; using iText.Kernel.Colors; +using iText.Kernel.Geom; using iText.Kernel.Pdf; using iText.Kernel.Pdf.Action; using iText.Kernel.Pdf.Canvas; @@ -53,9 +54,8 @@ namespace Elwig.Documents { IncludeSender = includeSender; } - protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { - base.RenderHeader(doc, pdf); - + protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { + base.BeforeRenderBody(doc, pdf); var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10); if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)")); Aside = new Table(ColsMM(22.5, 42.5)) @@ -68,6 +68,20 @@ namespace Elwig.Documents { .AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid)); } + protected void RenderAddress(Canvas canvas, Rectangle pageSize) { + canvas.Add(new Div() + .SetFixedPositionMM(25, 50, 80, 45, pageSize) + .SetFont(NF) + .Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargins(8, 0, 8, 0).SetHeight(16.0625f)) + .Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5))); + } + + protected static void RenderAside(Table aside, Canvas canvas, Rectangle pageSize) { + canvas.Add(new Div() + .SetFixedPositionMM(125, 50, 65, 50, pageSize) + .Add(aside)); + } + protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { base.RenderBody(doc, pdf); @@ -84,16 +98,10 @@ namespace Elwig.Documents { header.Add(new KernedParagraph(App.Client.NameTypeFull, 12).SetFont(NF).SetMargin(0)); canvas.Add(header); // address - canvas.Add(new Div() - .SetFixedPositionMM(25, 50, 80, 45, pageSize) - .SetFont(NF) - .Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargin(0).SetHeight(16).SetPaddings(8, 0, 8, 0)) - .Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5))); + RenderAddress(canvas, pageSize); // aside if (Aside != null) { - canvas.Add(new Div() - .SetFixedPositionMM(125, 50, 65, 50, pageSize) - .Add(Aside)); + RenderAside(Aside, canvas, pageSize); } } diff --git a/Elwig/Documents/CreditNote.cs b/Elwig/Documents/CreditNote.cs index 2e71831..3b5bd57 100644 --- a/Elwig/Documents/CreditNote.cs +++ b/Elwig/Documents/CreditNote.cs @@ -95,8 +95,8 @@ namespace Elwig.Documents { } } - protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { - base.RenderHeader(doc, pdf); + protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { + base.BeforeRenderBody(doc, pdf); Aside?.AddCell(NewAsideCell("Gutschrift", 2)) .AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-")) .AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}")) diff --git a/Elwig/Documents/DeliveryConfirmation.cs b/Elwig/Documents/DeliveryConfirmation.cs index 47633fd..38c32ce 100644 --- a/Elwig/Documents/DeliveryConfirmation.cs +++ b/Elwig/Documents/DeliveryConfirmation.cs @@ -31,8 +31,8 @@ namespace Elwig.Documents { MemberStats = AppDbContext.GetMemberStats(Season.Year, m.MgNr).GetAwaiter().GetResult(); } - protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { - base.RenderHeader(doc, pdf); + protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { + base.BeforeRenderBody(doc, pdf); var firstDay = Data.Rows.MinBy(r => r.Date)?.Date; var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date; Aside?.AddCell(NewAsideCell("Saison", 2)) diff --git a/Elwig/Documents/DeliveryNote.cs b/Elwig/Documents/DeliveryNote.cs index 05a6c16..d3e8c23 100644 --- a/Elwig/Documents/DeliveryNote.cs +++ b/Elwig/Documents/DeliveryNote.cs @@ -37,8 +37,8 @@ namespace Elwig.Documents { MemberBuckets = ctx?.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult() ?? []; } - protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { - base.RenderHeader(doc, pdf); + protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { + base.BeforeRenderBody(doc, pdf); Aside?.AddCell(NewAsideCell("Lieferung", 2)) .AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr)) .AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}")) diff --git a/Elwig/Documents/Document.cs b/Elwig/Documents/Document.cs index f16891e..9be1be1 100644 --- a/Elwig/Documents/Document.cs +++ b/Elwig/Documents/Document.cs @@ -88,11 +88,15 @@ namespace Elwig.Documents { } public int Render(string path) { - using var writer = new PdfWriter(path); - return Render(writer); + using (var writer = new PdfWriter(path)) { + Render(writer); + } + using var reader = new PdfReader(path); + using var pdf = new PdfDocument(reader); + return pdf.GetNumberOfPages(); } - private int Render(PdfWriter writer) { + private void Render(PdfWriter writer) { NF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\times.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED); BF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesbd.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED); IF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesi.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED); @@ -117,16 +121,14 @@ namespace Elwig.Documents { _doc = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4); try { _doc.SetFont(NF).SetFontSize(12); - RenderHeader(_doc, pdf); + BeforeRenderBody(_doc, pdf); RenderBody(_doc, pdf); - var pageNum = pdf.GetNumberOfPages(); - return pageNum; } finally { _doc.Close(); } } - protected virtual void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { } + protected virtual void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { } protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { } @@ -150,84 +152,77 @@ namespace Elwig.Documents { using var mergedPdf = new PdfDocument(writer); var merger = new PdfMerger(mergedPdf); - PdfPage? letterheadPage = null; - int letterheadInsertIndex = 0; - int letterheadDocIndex = 0; + (PdfPage Page, int InsertIndex, int DocIndex)? letterhead = null; + int p = mergedPdf.GetNumberOfPages(); for (int i = 0; i < m.Documents.Count; i++) { if (cancelToken?.IsCancellationRequested ?? false) throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!"); var doc = m.Documents[i]; - int p0 = mergedPdf.GetNumberOfPages(); + int p0 = p; - if (letterheadPage != null && doc is Letterhead) { - if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) { - mergedPdf.AddPage(letterheadPage); + if (letterhead != null && doc is Letterhead) { + if (p0 <= letterhead.Value.InsertIndex) { + mergedPdf.AddPage(letterhead.Value.Page); mergedPdf.AddNewPage(); } else { - mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage); - mergedPdf.AddNewPage(letterheadInsertIndex + 2); + mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page); + mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2); } - pageNums[letterheadDocIndex] = 1; - letterheadPage = null; + pageNums[letterhead.Value.DocIndex] = 1; + letterhead = null; + p += 2; } if (doc is RawPdfDocument) { - if (IsDoublePaged && doc is Letterhead) { - using var reader = new PdfReader(doc.PdfPath); - using var src = new PdfDocument(reader); - letterheadPage = src.GetPage(1).CopyTo(mergedPdf); - letterheadInsertIndex = p0; - letterheadDocIndex = i; - } else { - using var reader = new PdfReader(doc.PdfPath); - using var src = new PdfDocument(reader); - merger.Merge(src, 1, src.GetNumberOfPages()); - } + using var reader = new PdfReader(doc.PdfPath); + using var src = new PdfDocument(reader); + merger.Merge(src, 1, src.GetNumberOfPages()); + p += src.GetNumberOfPages(); } else { int pageNum = doc.Render(tmpPdf.FilePath); if (IsDoublePaged && doc is Letterhead) { using var reader = new PdfReader(tmpPdf.FilePath); using var src = new PdfDocument(reader); - letterheadPage = src.GetPage(1).CopyTo(mergedPdf); - letterheadInsertIndex = p0; - letterheadDocIndex = i; + letterhead = (src.GetPage(1).CopyTo(mergedPdf), p0, i); } else { using var reader = new PdfReader(tmpPdf.FilePath); using var src = new PdfDocument(reader); merger.Merge(src, 1, pageNum); + p += pageNum; } } - int p1 = mergedPdf.GetNumberOfPages(); + int p1 = p; pageNums.Add(p1 - p0); - if (IsDoublePaged && doc is not Letterhead && mergedPdf.GetNumberOfPages() % 2 != 0) { - if (letterheadPage != null) { - mergedPdf.AddPage(letterheadPage); - letterheadPage = null; + if (IsDoublePaged && doc is not Letterhead && p % 2 != 0) { + if (letterhead != null) { + mergedPdf.AddPage(letterhead.Value.Page); + letterhead = null; } else { mergedPdf.AddNewPage(); } + p++; } progress?.Report(100.0 * (i + 1) / (m.Documents.Count + 1)); } - if (letterheadPage != null) { - if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) { - mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf)); + if (letterhead != null) { + if (p <= letterhead.Value.InsertIndex) { + mergedPdf.AddPage(letterhead.Value.Page); mergedPdf.AddNewPage(); } else { - mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage.CopyTo(mergedPdf)); - mergedPdf.AddNewPage(letterheadInsertIndex + 2); + mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page); + mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2); } - - pageNums[letterheadDocIndex] = 1; + pageNums[letterhead.Value.DocIndex] = 1; + p += 2; } - TotalPages = pageNums.Sum(); + TotalPages = p; } catch { pdf.Dispose(); throw; @@ -394,6 +389,8 @@ namespace Elwig.Documents { } private void OnPageEnd(PdfDocumentEvent evt) { + if (_doc is Letterhead) return; + var pdf = evt.GetDocument(); var page = evt.GetPage(); var pageNum = pdf.GetPageNumber(page); diff --git a/Elwig/Documents/Letterhead.cs b/Elwig/Documents/Letterhead.cs index db3cf7c..3209f57 100644 --- a/Elwig/Documents/Letterhead.cs +++ b/Elwig/Documents/Letterhead.cs @@ -1,10 +1,21 @@ using Elwig.Models.Entities; +using iText.Kernel.Pdf; +using iText.Kernel.Pdf.Canvas; +using iText.Layout; namespace Elwig.Documents { public class Letterhead : BusinessDocument { public Letterhead(Member m) : base($"Briefkopf {m.FullName}", m, true) { - Aside = null; + } + + protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { + // do not render anything except this + var page = pdf.AddNewPage(); + var pageSize = page.GetPageSize(); + var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdf); + using var canvas = new Canvas(pdfCanvas, pageSize); + RenderAddress(canvas, pageSize); } } }