BaseSection.cs 8.01 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
using iText.IO.Image;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Properties;
using PDFGenerator.Models;
using PDFGenerator.Utilities;
using System.Collections.Generic;
using System.IO;
13
using System.Text.RegularExpressions;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using static PDFGenerator.Utilities.Globals;

namespace PDFGenerator.EvaluationReport
{
    public abstract class BaseSection
    {
        protected Document Document { get; set; }
        protected PdfOutline RootOutline { get; }
        protected Bookmarks Bookmarks { get; }
        protected TableOfContents TableOfContents { get; }
        protected static Text NewLine { get; } = new Text("\n");

        public BaseSection(Document document, Bookmarks bookmarks, TableOfContents tableOfContents)
        {
            Document = document;
            Bookmarks = bookmarks;
            TableOfContents = tableOfContents;

            // get the root outline from the PdfDocument: false indicates that
            // iText does not need to update the outlines
            RootOutline = Document.GetPdfDocument().GetOutlines(false);
        }

        /// <summary>
        /// Renders the content in each section.
        /// </summary>
        public abstract void Render();

        /// <summary>
        /// Gets the current page.
        /// </summary>
45
        /// <returns>the current page</returns>
46
47
48
49
50
51
52
53
        protected int GetCurrentPage()
        {
            return Document.GetPdfDocument().GetNumberOfPages();
        }

        /// <summary>
        /// Gets default page size. 
        /// </summary>
54
        /// <returns>the default page size</returns>
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
        protected PageSize GetPageSize()
        {
            return Document.GetPdfDocument().GetDefaultPageSize();
        }

        /// <summary>
        /// Resizes image to fit page size.
        /// </summary>
        /// <param name="image">image to be resized</param>
        /// <returns>the resized image</returns>
        protected Image GetScaledImage(Image image)
        {
            PageSize pageSize = GetPageSize();
            float maxWidth = pageSize.GetWidth() - Document.GetLeftMargin() - Document.GetRightMargin();
            float maxHeight = pageSize.GetHeight() - Document.GetTopMargin() - Document.GetBottomMargin();

            if (image.GetImageWidth() > maxWidth || image.GetImageHeight() > maxHeight)
            {
                return image.ScaleToFit(maxWidth, maxHeight);
            }

            return image;
        }

        /// <summary>
        /// Adds upload files directly to the document if they are images; uploads consisting of PDF files are
        /// added to the available custom uploads to be rendered as attachments in appendix and links are added to the document referring to them; 
        /// if the custom uploads are neither PDF nor image files, then an exception is triggered.
        /// </summary>
        /// <param name="uploads">new custom uploads to be considered</param>
        /// <param name="customUploads">already available custom uploads</param>
        protected void AddCustomUploads(CustomUploads uploads, Dictionary<string, byte[]> customUploads)
        {
            if (uploads.Files == null)
            {
                if (!string.IsNullOrEmpty(uploads.Paragraph))
                {
                    Document.Add(ParagraphFactory.GetStandardParagraph(uploads.Paragraph));
                    return;
                }

                return;
            }

            bool imagesAvailable = false;
            foreach (KeyValuePair<string, byte[]> file in uploads.Files)
            {
                // only accept files in image or PDF format, otherwise an exception is triggered below
                // firstly, check if file is a valid image
                if (ImageDataFactory.IsSupportedType(file.Value))
                {
                    ImageData imageData = ImageDataFactory.Create(file.Value);
                    Image image = new Image(imageData)
                        .SetMarginTop(10f)
                        .SetHorizontalAlignment(HorizontalAlignment.CENTER)
                        .SetMarginBottom(15f);

                    AddScaledImage(image);
                    imagesAvailable = true;

                    continue;
                }

                // secondly, if data does not correspond to a PDF file, an exception is triggered
                new PdfReader(new MemoryStream(file.Value));

                if (!customUploads.ContainsKey(file.Key))
                {
                    customUploads.Add(file.Key, file.Value);
                }

                // ensure that the sentence is only written once
                if (customUploads.Count == 1)
                {
                    Document.Add(ParagraphFactory.GetStandardParagraph("Weitere Dokumente siehe Anhang."));
                }

                Document.Add(
                    ParagraphFactory.GetStandardParagraph(file.Key)
                    .SetMarginTop(-2f)
                    .SetAction(PdfAction.CreateGoTo(file.Key))
                );
            };

            if (!imagesAvailable && !string.IsNullOrEmpty(uploads.Paragraph))
            {
                Document.Add(ParagraphFactory.GetStandardParagraph(uploads.Paragraph));
            }
        }

        /// <summary>
        /// Adds paragraph above the table.
        /// </summary>
        /// <param name="table">the table, on which the paragraph is added</param>
        /// <param name="text">the paragrah content</param>
        /// <param name="header">flag indicatesm whether the content is a hedaer for the table</param>
        /// <param name="style">given style for paragraph</param>
        protected void AddParagraphWithLeadingToTable(Table table, string text, bool header, Style style = null)
        {
            Cell cell = new Cell().SetBorder(Border.NO_BORDER);
            Paragraph p;

            if (header)
            {
                cell.SetPaddingTop(12.5f).SetPaddingBottom(7f);
                p = ParagraphFactory.GetTableHeaderParagraph(text, style);
            }
            else
            {
                cell.SetPaddingTop(0f);
                p = ParagraphFactory.GetStandardParagraph(text);
            }
            p.SetKeepTogether(true);

            cell.Add(p);
            table.AddCell(cell);
        }

        /// <summary>
        /// Changes the page orientation.
        /// </summary>
176
        /// <param name="orientation">orientation that the page should assume</param>
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
        protected void SetPageOrientation(Orientation orientation)
        {
            if (orientation == Orientation.Landscape)
            {
                Document.GetPdfDocument().SetDefaultPageSize(PageSize.A4.Rotate());
                return;
            }

            Document.GetPdfDocument().SetDefaultPageSize(PageSize.A4);
        }

        /// <summary>
        /// Adds line break to document.
        /// </summary>
        protected void AddLineBreak()
        {
            Document.Add(ParagraphFactory.GetTableHeaderParagraph(string.Empty));
        }

196
197
198
199
200
201
202
203
204
205
206
        /// <summary>
        /// Prevents the default trim of existent leading whitespaces at the string beginning and immediately after a linebreak on iText7,
        /// by adding a NULL character ('\u0000')
        /// </summary>
        /// <param name="text">input text</param>
        /// <returns>text with preserved leading whitespaces</returns>
        protected string PreserveLeadingSpaces(string text)
        {
            return "\u0000" + Regex.Replace(text, @"\n", "\n\u0000");
        }

207
208
209
210
211
212
213
214
215
216
217
        /// <summary>
        /// Adds page break to document.
        /// </summary>
        public void AddPageBreak()
        {
            Document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        }

        /// <summary>
        /// Adds scaled image to document.
        /// </summary>
218
        /// <param name="image">image to be scaled</param>
219
220
221
222
223
224
        private void AddScaledImage(Image image)
        {
            Document.Add(GetScaledImage(image));
        }
    }
}