User Manual
Go to AdmCloud
Available in All plans
Guides

Complete Guide: Customizing Printing Formats

This guide explains in depth how AdmCloud's custom printing formats mechanism works: what happens internally when you print, the language the formats support, how to create and configure them, how to use the document's variables with real examples, where to look up every available variable, how to see the live preview and how to make the format active. It's a conceptual and practical guide; for the quick reference of each screen see HTML Printing Formats and HTML Variables for Printing Formats.

Topic: Customization Requires the "Document Printing Formats" permission

What it is and how it works under the hood

Every document AdmCloud generates (an invoice, a quote, a purchase order, a reception, a payroll action, etc.) has a default printing format. A custom printing format lets you replace that standard design with your own: you write HTML mixed with Razor code and AdmCloud turns it into the final document, replacing each expression with the real data (customer, lines, totals, taxes, your company's information, etc.).

The full cycle, from start to finish, is:

  1. You tie the format to a document type (the Object field). That type determines which data will be available: each document type has its own data "model".
  2. You write your template using HTML for the layout and Razor expressions (@Model.Property) to insert the data.
  3. You activate it as the default format for that document type (under Default Printing Formats), at the company or subsidiary level.
  4. When printing or generating the PDF, AdmCloud loads the real document, builds the matching data model, compiles your template replacing each expression with the real value and produces the result: a paginated PDF or a single HTML page.

It is different from Check Printing Formats: those position individual data by coordinates over a pre-printed check, whereas a custom printing format draws the complete document (borders, tables, colors, images) from start to finish.

Language supported by the formats

Formats are written in HTML for the structure and styling, combined with Razor (the same syntax used by ASP.NET views, based on C#) to insert data and apply logic. In practice this means you can use:

  • Any HTML and CSS you need: tables, div, images, inline styles or a <style> tag, fonts, colors, etc.
  • Data expressions with @Model.Property (for example @Model.CompanyInfo.CompanyName).
  • Conditionals with @if (...) { ... } to show or hide parts of the document.
  • Loops with @foreach (var line in Model.Header.Items) { ... } to walk the document's lines.
  • Value formatting with .NET methods, for example @Model.Header.DocDate.ToString("dd/MM/yyyy") or @value.ToString("N2") for two decimals.
ℹ️

The {page}, {total-pages}, {date} and {time} tokens are not Razor: they only make sense in the HTML Header and HTML Footer of the PDF mode, and the PDF generator replaces them with the current page, the total number of pages, and the print date and time.

⚠️

For security, a format's code can only read and display the document's data. The system blocks saving if it detects instructions considered dangerous (database access, connection strings, system configuration, etc.). A format is for designing and presenting, not for running operations. The code can only use what formats allow: it cannot read files, system variables or use reflection (GetType(), typeof); if it tries, the system rejects saving (and the preview) showing which element and on which line. Also, a format that takes more than 30 seconds (for example, because of a loop that never ends) or a function that calls itself endlessly is stopped with an error instead of being printed.

How to create a format, step by step

  1. Go to HTML Printing Formats and use the New from Template menu. Pick Empty to start from scratch, or select a document type to start from a ready-made sample design for that document (the list only shows the documents enabled in your plan).
  2. In Name, give it a unique, descriptive name (for example, "A4 Invoice with logo").
  3. In Object, select the document type it applies to. This field defines which variables you will have available and which sample data you'll see in the preview. (It is hidden automatically if the format is created from a Custom Record.)
  4. Choose the output type: turn on PDF for a paginated document (with margins and a header/footer repeated on every page), or leave it off to print as a single HTML page (typical for thermal or dot-matrix printers).
  5. In the HTML Format tab, write your template. Lean on the sample template below and on the Data Dictionary to know which fields exist.
  6. Check the live preview in the right-hand panel and fix whatever is needed.
  7. Click Save.
  8. Activate it under Default Printing Formats for the matching document type. Until you assign it there, the saved format does not change what your users see when printing.

How it is configured

Field What it is for
NameIdentifies the format in the list and when assigning it as the default format. Required and unique.
ObjectDocument type it applies to. Determines the available variables and the preview's sample data.
PDFOn: generates a paginated PDF with margins and its own header/footer. Off: prints as a single HTML page.
Top / Bottom / Left / Right MarginWhite space around the content in PDF mode.
Header Height / Footer HeightHeight reserved on each PDF page for the header and footer.
HTML Header / HTML FooterCode repeated at the top and bottom of every PDF page. Supports {page}, {total-pages}, {date} and {time}.
HTML FormatThe main code (HTML + Razor) that draws the body of the document with the real data.
OwnerUser responsible for the format.
Only allow the owner to access the structureIf on, only the Owner can view or edit the code; everyone else can only use the format if it's assigned as a default.

The Model variables: how they work

The Model object represents the document you are printing. You access its data with @Model. followed by the property name. Many properties are objects that in turn have their own properties, so you chain them with dots: @Model.Relationship.Name (the customer's name), @Model.CompanyInfo.CompanyName (your company's legal name), @Model.Header.DocDate (the document's date).

All document types share a base group of properties. The most used ones:

VariableWhat it holds
Model.CompanyInfoYour company's data: legal name, tax ID, address, phone numbers.
Model.LogoYour company's configured logo (use Model.Logo.URI as the image source).
Model.RelationshipThe document's customer, vendor or contact (for example Model.Relationship.Name).
Model.HeaderThe transaction header: number, date, totals, currency, etc.
Model.Header.ItemsThe list of lines (items or services) of the document, to iterate with a loop.
Model.Header.Items.ItemThe item or service of each line, with its code, description, unit, etc.
Model.CaptionThe visible name of the document type (for example, "Credit Invoice").

On top of that base, each document type adds its own variables. For example, a sales invoice usually has Model.Terms (payment terms), Model.SalesRep (sales rep), Model.Taxes (tax summary), Model.Currency (currency) or Model.FiscalSequenceType (fiscal receipt type), whereas a Sales Order adds Model.Stock (the item's available inventory).

⚠️

Variable names are case-sensitive and are always prefixed with Model.. A misspelled or non-existent name produces a compilation error when previewing or printing.

Sample template

This is a simple credit-invoice format. It shows the logo (or the company name if there's no logo), the customer and document data, and walks the lines to build the table:

<div class="invoice">
    <header>
        @if (Model.Logo != null)
        {
            <img src="@Model.Logo.URI" alt="Logo" style="max-height:70px;" />
        }
        else
        {
            <h1>@Model.CompanyInfo.CompanyName</h1>
        }
        <p>Tax ID: @Model.CompanyInfo.TaxID</p>
    </header>

    <h2>@Model.Caption No. @Model.Header.Number</h2>
    <p>Customer: @Model.Relationship.Name</p>
    <p>Date: @Model.Header.DocDate.ToString("dd/MM/yyyy")</p>

    @if (!string.IsNullOrEmpty(Model.FiscalSequenceType))
    {
        <p>Receipt type: @Model.FiscalSequenceType</p>
    }

    <table border="1" cellspacing="0" cellpadding="4" width="100%">
        <thead>
            <tr>
                <th>Item</th>
                <th>Quantity</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var line in Model.Header.Items)
            {
                <tr>
                    <td>@line.Item.Description</td>
                    <td align="right">@line.Quantity</td>
                    <td align="right">@line.Price.ToString("N2")</td>
                </tr>
            }
        </tbody>
    </table>
</div>

And this would be a typical HTML Footer for the PDF mode, using the special pagination variables:

<div style="text-align:center; font-size:10px; color:#666;">
    Page {page} of {total-pages} &mdash; Printed on {date} at {time}
</div>
ℹ️

The exact property names of the lines (quantity, price, amount, etc.) vary by document. Always confirm them in the Data Dictionary or in HTML Variables for Printing Formats before assuming them.

Where to look up the available variables

You have two ways to know exactly what you can use in each document:

  • Data Dictionary tab (inside the editor itself, when enabled for your account): when you pick the Object, it shows the name and type of each property of the document, including lists (such as the lines) and nested objects. It's the most convenient way because you consult it without leaving the editing screen.
  • The HTML Variables for Printing Formats screen (address /PFDocumentation): a standalone reference that documents, document by document, each field, its description and its data type. When a field is an object or a list, a link takes you to the Data Dictionary of that table to see its inner fields (for example, Header.Items.Item.Description).

How to see the live preview

While you edit, the right-hand panel shows a live preview of the format, rendered with sample data inside an isolated box that does not touch real information. This lets you test colors, tables and text freely.

  • The preview is generated when the screen loads, when you change the Object and every time you click the Refresh button.
  • It uses the editor's current content, not the saved version, so you instantly see the latest thing you wrote.
  • If your code has a compilation error, instead of the design you'll see the error message telling you what to fix.

Activating the format and other options

  • Activate it: a saved format is not used on its own. You must assign it under Default Printing Formats, at the company or subsidiary level, for the matching document type.
  • Modify with AI (if available): with the Modify with AI button you describe in plain language what you want to change ("change the main color to blue", "make the logo bigger") and the AI rewrites the code; review it before saving.
  • Access control: with Only allow the owner to access the structure you restrict editing and viewing of the code to the Owner only.
  • Transfer to another company you administer (requires the Enterprise plan with the "Create Plugins" feature).

Tips and common mistakes

💡

Always start from a sample template for the document type you need (the "New from Template" menu) instead of from scratch: it already has the right structure and the most common variables in use.

⚠️

Does the preview show an error instead of the design? It's a compilation error in your code: check that each @Model.Property exists for the selected Object (look it up in the Data Dictionary) and that the HTML tags are properly closed.

ℹ️

Did you save the format but printing still shows the old design? You still need to assign it under Default Printing Formats for the document type; saving the format on its own does not activate it.