Browse Source

Transferred changes from another https://github.com/QuestPDF/QuestPDF/pull/367

MarcinZiabek 2 years ago
parent
commit
abe3102592

+ 1 - 1
Source/QuestPDF.Examples/Engine/RenderingTest.cs

@@ -109,7 +109,7 @@ namespace QuestPDF.Examples.Engine
             Render(document);
         }
         
-        private void Render(IDocument document)
+        public void Render(IDocument document)
         {
             if (ResultType == RenderingTestResult.Images)
             {

+ 65 - 0
Source/QuestPDF.Examples/MergedDocumentExamples.cs

@@ -0,0 +1,65 @@
+using NUnit.Framework;
+using QuestPDF.Examples.Engine;
+using QuestPDF.Fluent;
+
+namespace QuestPDF.Examples
+{
+    [TestFixture]
+    public class MergedDocumentExamples
+    {
+        [Test]
+        public void Merge_ContinuousPageNumbers()
+        {
+            var mergedDocument = Document.Merge(
+                    CreateDocument("Document 1"),
+                    CreateDocument("Document 2"),
+                    CreateDocument("Document 3"))
+                .ContinuousPageNumbers();
+
+            RenderingTest
+                .Create()
+                .ProducePdf()
+                .ShowResults()
+                .Render(mergedDocument);
+        }
+
+        [Test]
+        public void Merge_SeparatePageNumbers()
+        {
+            var mergedDocument = Document.Merge(
+                    CreateDocument("Document 1"),
+                    CreateDocument("Document 2"),
+                    CreateDocument("Document 3"))
+                .SeparatePageNumbers();
+
+            RenderingTest
+                .Create()
+                .ProducePdf()
+                .ShowResults()
+                .Render(mergedDocument);
+        }
+
+
+        private static Document CreateDocument(string content)
+        {
+            return Document.Create(d =>
+            {
+                d.Page(p =>
+                {
+                    p.Content().AlignMiddle().AlignCenter().Column(c =>
+                    {
+                        c.Item().Text(content).FontSize(40);
+                        c.Item().PageBreak();
+                        c.Item().Text(content).FontSize(40);
+                    });
+                    p.Footer().AlignCenter().PaddingVertical(20).Text(t =>
+                    {
+                        t.CurrentPageNumber();
+                        t.Span(" / ");
+                        t.TotalPages();
+                    });
+                });
+            });
+        }
+    }
+}

+ 20 - 4
Source/QuestPDF/Drawing/DocumentGenerator.cs

@@ -96,6 +96,26 @@ namespace QuestPDF.Drawing
         
         internal static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document, DocumentSettings settings, bool useOriginalImages = false)
             where TCanvas : ICanvas, IRenderingCanvas
+        {
+            if (document is MergedDocument { PageNumberHandling: MergedDocumentPageNumberHandling.Separate } mergedDocument)
+            {
+                canvas.BeginDocument();
+                
+                foreach (var singleDocument in mergedDocument.Documents)
+                    RenderDocumentImpl(canvas, singleDocument, settings, useOriginalImages);
+                
+                canvas.EndDocument();
+                
+                return;
+            }
+
+            canvas.BeginDocument();
+            RenderDocumentImpl(canvas, document, settings, useOriginalImages);
+            canvas.EndDocument();
+        }
+        
+        internal static void RenderDocumentImpl<TCanvas>(TCanvas canvas, IDocument document, DocumentSettings settings, bool useOriginalImages = false)
+            where TCanvas : ICanvas, IRenderingCanvas
         {
             var container = new DocumentContainer();
             document.Compose(container);
@@ -120,8 +140,6 @@ namespace QuestPDF.Drawing
         {
             InjectDependencies(content, pageContext, canvas);
             content.VisitChildren(x => (x as IStateResettable)?.ResetState());
-            
-            canvas.BeginDocument();
 
             var currentPage = 1;
             
@@ -162,8 +180,6 @@ namespace QuestPDF.Drawing
 
                 currentPage++;
             }
-            
-            canvas.EndDocument();
 
             void ThrowLayoutException()
             {

+ 11 - 0
Source/QuestPDF/Fluent/MinimalApi.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using QuestPDF.Drawing;
 using QuestPDF.Infrastructure;
 
@@ -32,6 +33,16 @@ namespace QuestPDF.Fluent
             return this;
         }
         
+        public static IMergedDocument Merge(IEnumerable<IDocument> documents)
+        {
+            return new MergedDocument(documents);
+        }
+
+        public static IMergedDocument Merge(params IDocument[] documents)
+        {
+            return new MergedDocument(documents);
+        }
+        
         #region IDocument
 
         public DocumentMetadata GetMetadata() => Metadata;

+ 88 - 0
Source/QuestPDF/Infrastructure/IMergedDocument.cs

@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace QuestPDF.Infrastructure
+{
+    public interface IMergedDocument : IDocument
+    {
+        /// <summary>
+        /// Each document should be treated as a 'single' one in terms of page numbering.
+        /// Page numbers will be reset after each document is generated.
+        /// E.g. two documents with a page count of 2 and 3 will result in the following page numbers: 1,2,1,2,3.
+        /// </summary>
+        IMergedDocument SeparatePageNumbers();
+
+        /// <summary>
+        /// All documents should be treated as a 'single' document in terms of page numbering.
+        /// Page numbers will continue to increase throughout the document generation.
+        /// E.g. two documents with a page count of 2 and 3 will result in the following page numbers: 1,2,3,4,5.
+        /// </summary>
+        IMergedDocument ContinuousPageNumbers();
+
+        IMergedDocument WithMetadata(DocumentMetadata metadata);
+        IMergedDocument WithSettings(DocumentSettings settings);
+    }
+
+    internal enum MergedDocumentPageNumberHandling
+    {
+        Separate,
+        Continuous,
+    }
+
+    internal sealed class MergedDocument : IMergedDocument, IDocument
+    {
+        public IReadOnlyList<IDocument> Documents { get; }
+
+        public MergedDocumentPageNumberHandling PageNumberHandling { get; private set; } = MergedDocumentPageNumberHandling.Separate;
+        public DocumentMetadata Metadata { get; private set; } = DocumentMetadata.Default;
+        public DocumentSettings Settings { get; private set; } = DocumentSettings.Default;
+
+        public MergedDocument(IEnumerable<IDocument> documents)
+        {
+            Documents = documents?.ToList() ?? throw new NullReferenceException(nameof(documents));
+        }
+
+        public void Compose(IDocumentContainer container)
+        {
+            foreach (var document in Documents)
+            {
+                document.Compose(container);
+            }
+        }
+
+        public DocumentMetadata GetMetadata()
+        {
+            return Metadata;
+        }
+        
+        public DocumentSettings GetSettings()
+        {
+            return Settings;
+        }
+
+        public IMergedDocument SeparatePageNumbers()
+        {
+            PageNumberHandling = MergedDocumentPageNumberHandling.Separate;
+            return this;
+        }
+
+        public IMergedDocument ContinuousPageNumbers()
+        {
+            PageNumberHandling = MergedDocumentPageNumberHandling.Continuous;
+            return this;
+        }
+
+        public IMergedDocument WithMetadata(DocumentMetadata metadata)
+        {
+            Metadata = metadata ?? Metadata;
+            return this;
+        }
+
+        public IMergedDocument WithSettings(DocumentSettings settings)
+        {
+            Settings = settings ?? Settings;
+            return this;
+        }
+    }
+}