1. Subject and purpose of the guide
This guide describes the programming of print templates in PDF format using an external function. A programmed print template is used where ordinary print templates are not enough for the look of the document – typically for invoices, quotations and other documents with a precise graphic layout, a letterhead or embedded attachments.
The basic principle: the document is designed as HTML with inline styles, and NET Genium takes care of the conversion to PDF as well as the finishing work – laying the letterhead under every page, page numbering, fold marks, embedding attachments into the PDF and converting the document to the archival PDF/A format. The external function therefore needs no PDF library of its own.
Creating print templates in PDF format requires:
- The “ngef” external functions project with a reference to the “NETGeniumConnection.dll” library
- NET Genium installed on the local computer
A detailed description of ordinary print templates is provided in the separate guide Print templates. A detailed description of external functions is provided in the separate guide External functions.
2. How printing via an external function works
- A print template with the “pdf” extension is stored in the “Templates” directory of the NET Genium instance. The content of this file does not matter – it serves as the initial document that the external function overwrites.
- An edit form or a view page contains a button with this print template selected.
- After the button is pressed, NET Genium copies the template to a temporary file and calls the “NETGenium.OnAfterPrint” external function.
- The external function recognizes the print job by the template name, builds the document and hands it back to NET Genium.
- NET Genium finishes the document and offers it to the user for download.
The “NETGenium.OnAfterPrint” external function runs after every print template of the instance is printed – including templates in the “txt”, “csv”, “html”, “xlsx” or “docx” formats – just before the file is sent to the client station. The specific print job is recognized by the template name in the “conn.PrintingProcess.Template” variable.
When a record is printed from an edit form, the values of the printed record are available in the external function in the standard way, e.g. “conn["ng_number"]”. When printing from a view page, no specific record is passed.
3. The PrintingProcess object
The current print job is described by the “conn.PrintingProcess” object with the following properties:
- FilePath – the path of the file being printed. Whatever is at this path when the print job and the finishing work are done is what NET Genium sends to the user.
- FileName – the name of the file offered to the user for download – can be changed. NET Genium decides by the extension whether the document is a PDF – only a file with the “pdf” extension is converted to the archival PDF/A format.
- Template – the name of the print template, by which the external function recognizes the specific print job.
- Content – the content of the printed file for templates in the “txt”, “csv”, “htm” and “html” formats, i.e. the text of the template with the variables already replaced – can be changed. For all other formats it is “null” and changing it has no effect.
- Form – the ID of the edit form the print job was started from; 0 when printing from a view page.
- ViewPage – the ID of the view page the print job was started from; 0 when printing from an edit form.
- SaveAs – the way the document is finished. When it stays “null”, the file at “FilePath” is sent as it is. Assigning a “SaveAsPdf” object finishes the document as a PDF – see the next chapter.
4. The SaveAsPdf class
A “PrintingProcess.SaveAsPdf” object assigned to the “conn.PrintingProcess.SaveAs” property tells NET Genium to finish the document as a PDF. Properties:
- Html – the HTML that NET Genium converts into the PDF. When it stays empty, no conversion takes place and the file at “FilePath” is taken to be the finished PDF – the variant for external functions that produce the PDF themselves, see chapter 7.
- MarginTop, MarginRight, MarginBottom, MarginLeft – the page margins in millimetres; the default value is 20 mm.
- FooterHtml – the HTML of the footer repeated at the bottom of every page. The footer is rendered once, so it cannot contain anything that differs from page to page – page numbering belongs in the “PageNumbering” property.
- FooterHeight – the height reserved for the footer in millimetres; a footer given less room than it needs is clipped.
- PageNumbering – the page numbering stamped into the bottom right corner of every page. The “#” character stands for the number of the current page, “{0}” for the total number of pages – e.g. “Page # / {0}”. When it stays empty, the pages are not numbered.
- BackgroundFilePath – the path of a PDF file whose first page is laid under every page of the printed document – typically a letterhead. The background shows only where the document leaves the page blank.
- FoldMarks – a pair of short marks in the left and the right margin of every page that show where the printed document is to be folded so that it fits a long (DL) envelope (a third of the A4 height).
- Attachments – files embedded into the printed PDF, e.g. the ISDOC of an invoice – see chapter 5.
The finishing work takes place in this order:
- Conversion of “Html” into the PDF using the four margins and the footer
- Laying “BackgroundFilePath” under every page
- Drawing the “FoldMarks”
- Stamping the “PageNumbering”
- Embedding the “Attachments”
- Conversion to the archival PDF/A-2a format, or PDF/A-3a when attachments are embedded
The document is converted to the archival format only when the “PDF_A_2A.txt” file is stored in the “Config” directory of the NET Genium installation on the server and the file name in the “FileName” property ends with the “pdf” extension.
5. Attachments embedded into the PDF
Any files can be embedded into the printed PDF – typically the ISDOC of an invoice. Attachments are added to the “Attachments” collection and are created in three ways:
// A file on the disk, embedded under its own name
pdf.Attachments.Add(new PrintingProcess.Attachment(filePath));
// A file on the disk, embedded under the given name
pdf.Attachments.Add(new PrintingProcess.Attachment(filePath, "Invoice.isdoc"));
// Content held in memory - a document built by the external function does not have to be written to the disk
pdf.Attachments.Add(new PrintingProcess.Attachment(contentBytes, "Invoice.isdoc"));
A file passed by path is read into memory the moment the attachment is created, so it does not have to stay on the disk until the print job finishes.
6. Sample external function
The “NETGenium.OnAfterPrint” external function is registered in the “ngef.cs” class:
case "NETGenium.OnAfterPrint": Print.OnAfterPrint(args, conn); return "";
The print template itself then looks for example like this:
using NETGenium;
using System.Text;
namespace ExternalFunctions
{
public class Print
{
public static void OnAfterPrint(string[] args, DbConnection conn)
{
if (conn.PrintingProcess.Template == "Invoice.pdf")
{
StringBuilder sb = new StringBuilder();
sb.Append("<div style=\"font-family: Calibri; font-size: 10pt;\">");
sb.Append("<h1>Invoice " + conn["ng_number"] + "</h1>");
sb.Append("<p>Date of issue: " + conn.User.FormatDate(Parser.ToDateTime(conn["ng_date"])) + "</p>");
sb.Append("</div>");
var pdf = new PrintingProcess.SaveAsPdf();
pdf.Html = sb.ToString();
pdf.FooterHtml = "<div style=\"font-family: Calibri; font-size: 8pt; text-align: center;\">www.company.com</div>";
pdf.FooterHeight = 12;
pdf.PageNumbering = "Page # / {0}";
conn.PrintingProcess.SaveAs = pdf;
conn.PrintingProcess.FileName = "Invoice " + conn["ng_number"] + ".pdf";
}
}
}
}
Recommendations for building the HTML:
- Use inline styles – the document is converted without external CSS files.
- The page has the A4 format; the width of the content is determined by the margins set in the “MarginLeft” and “MarginRight” properties.
7. A custom PDF without the HTML conversion
The external function can also produce the PDF itself and write it directly to the file at “conn.PrintingProcess.FilePath”. In that case:
- When the document needs no finishing work, the “SaveAs” property is not set.
- When the document is to get a letterhead, page numbering, fold marks or attachments, the “SaveAs” property is set to a “SaveAsPdf” object with an empty “Html” property – the file at “FilePath” is then taken to be the finished PDF and all the other finishing work is carried out on it.
8. Creating the print template and the button in NET Genium
- Store a print template file with the “pdf” extension, e.g. “Invoice.pdf”, in the “Templates” directory of the NET Genium instance – the content can be any PDF, because the external function overwrites it during printing.
- Place a “Button” control on the edit form and select the “Invoice.pdf” print template in its settings.
- Upload the compiled “ngef.dll” library to the “bin” directory of the NET Genium instance.
- Open a record and press the button – NET Genium offers the finished document for download.
A detailed description of the button settings is provided in the separate guides Edit form – Button and View page – Button.