> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/appian/template-generation/sample-docgen-app.md).

# Sample App - Generating invoices in Appian with WebViewer

Learn how to generate invoices in Appian using WebViewer. This guide walks you through creating a PDF invoice from an Appian data entity with placeholders. Perfect for those familiar with Appian Desig

This guide will guide you through the process of generating invoices in Appian using WebViewer by making an example application. This application will take some invoice data from an Appian data entity, and generate a PDF invoice using a template. The template will be an Office document with placeholders that will be replaced with the data from your data entity. This guide also assumes you have some basic knowledge of Appian, and working with the Appian Designer.

## Preparing the template

Let us assume we have a business that sells PC parts called `Business Corp`, and we have the following [invoice template](https://sdk.apryse.com/files/invoice_template.docx):

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-90d6bffcbbdcc726783f8bc2773d8ee45c3a75ac%2Fb7845a0f319b614c80bfc3f87f408ef5b3810036-709x630.png?alt=media)

The fields we have in the following template are as follows:

| Field               | Description                                                                               |
| ------------------- | ----------------------------------------------------------------------------------------- |
| {{invoice\_number}} | The invoice number.                                                                       |
| {{bill\_to\_name}}  | The person we are billing to.                                                             |
| {{ship\_to\_name}}  | The person we are shipping to.                                                            |
| {{loop items}}      | The `loop` keyword signals the start of a loop to loop through a property called `items`. |
| {{qty}}             | The quantity of a line item in the invoice.                                               |
| {{description}}     | The description of a line item in the invoice.                                            |
| {{price}}           | The unit price of a line item in the invoice.                                             |
| {{total}}           | The total price of a line item in the invoice.                                            |
| {{endloop}}         | The `endloop` keyword signals the end of a loop.                                          |
| {{subtotal}}        | The subtotal of the invoice.                                                              |
| {{sales\_t}}        | The tax of the invoice.                                                                   |
| {{sales}}           | The total tax of the invoice.                                                             |
| {{total\_t}}        | The total of the invoice including tax.                                                   |

For the totals in the invoice, we will be storing them in our data entity, but you could also opt to dynamically calculate them in Appian with an expression.

## Setting up the Appian application

To start off in Appian, we will need an application that will allow us to view these invoices. Thus, we will start by creating one called `Document Generation Sample`, however, you can name this whatever you want or even use an existing application.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-076dd64194f8d9062f45e6d227310d2f0123720b%2Fb8c38f095394cafdf664f281b398aef93e524cbd-1608x236.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-174fa129658ae12dfa8e33778466c941319eb187%2F442eeb1c8bc03cda51edea4a788160e8a05ed839-737x365.png?alt=media)

## Creating the data entities

Once the app is created, we will add data entities or a record type to our application. We will need two data entities, one for the invoice, and one for the line items. We will call them `Invoice`, and `Invoice Line Item` respectively.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-093f884faedd45acde13ff2783ed291162b2465a%2F5deb34f9e866a07f5b47a42c8c85cb949ff8767d-1204x720.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-7f6862ea67f351ee52db4af276633a5b16c39a68%2F8c568fe02a573ba0b5fa1571da39bbf5a80b7e18-726x398.png?alt=media)

For this guide, we will create a new database table from scratch. You could also modify an existing table if you have one, but do not forget to update your data types, and data stores in the Appian Designer.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-453ad5dafb41c7ba33aafc2f1ba13da1b0365aa3%2F2de042b122af85a7461aa6205090cf7bcd7a3831-1206x1222.png?alt=media)

We will then add 6 fields to our table at the invoice level for the data found on the invoice. Feel free to name them however you like as we can map them later as necessary. You can optionally keep the predefined user, and date fields if you would like.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-0ec4d6a6d8db1ed979ddb0f13e8927d768cbf95c%2F06938224aec4980d1a1f49d6411ea384cb8b14a3-2005x1220.png?alt=media)

Finally, after a few more steps, we can save our `Invoice` entity. We can then return to the Appian Designer to create a data type, and data store for this entity. Fortunately, this can be done together. For now, we will name the data type `DGS_INVOICE`. Afterwards, we will need a constant for the data store to use in an expression. We will name the constant `DGS_Invoices_DS`, but feel free to name it however you like.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-e93a1b0443df1250c92935d34011c2e06fe77a7f%2Fa96591b711b65692d784d782010f1611c2cd7ccb-1448x830.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-21d608e39c02066e9056f641d5a5893c893e9a7c%2Fd339e6f1cacf7c7d39f4b1bb1dc0ea7910b9619d-2410x1720.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-27350f75de1a80411ac6b0ba1ad345aee906210a%2F4076cf0702fa34f47150da0b37471b071d132f59-2410x1722.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-abab07b2345825d63c41640b0f755ce68d5532b8%2F284d7f1f4385e7b7890ea9bd38364cd63b010c3c-1448x1290.png?alt=media)

We will then need to return to the Appian Designer, and repeat the steps to create a new entity for the line items. We will call the new data entity `Invoice Line Item`. We will also add the line item fields to the data entity.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-c8d69adb783b4342f2c54650a372a393490a6143%2F918a6aba1f28bee2f3e5fcd0839778bd938d8245-724x397.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-790d8f7cf6415ce3495094c0353e752f88c46ae1%2Fd6b2619f3dd9437823a0fd51b5e2004e09938b07-2006x1221.png?alt=media)

Before finalizing, and creating the line item table, we will also need to set up a relationship between the `Invoice`, and `Invoice Line Item` entities. We will do this by using the `invoiceId` field in the `Invoice Line Item` entity, and set it to be a foreign key to the `Invoice` entity.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-1f595a955eecb5bfe46ef166ae755314119d0943%2F744a21f5376c6222ba475ba7b2db7beca4cecf80-1207x601.png?alt=media)

Before adding the connected systems, we will also have to add a data type (`DGS_INVOICE_LINE_ITEM`), and data store for the line items the same way we did for the invoice type. As before, we will also add a constant called `DGS_InvoiceLineItems_DS` to use in the query expression later.

## Adding the WebViewer Connected Systems

The connected systems allows WebViewer to load, and save documents to, and from Appian. We just have to add a connected systems through the designer, and select `WebViewer Connected System Plug-in`. For the user field, you must provide an Appian user with the correct permissions to read/write documents to a particular folder. You can leave the rest empty for now.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-917aae83ea197c535f570679b34254169106ff72%2F85d148b48d714689329e531c5891e8de5501b290-726x720.png?alt=media)

To provide WebViewer this connected system, we will need to create a constant. We will call this constant `DGS_WVCS` for short, and set the value to the connected system we just created. Feel free to name this constant whatever you like.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-291559212e357fb268f8337ddc171a3f15a6a740%2F404863ab5754f9bc506658ed39e21b409c8215f7-723x646.png?alt=media)

## Upload the template

Next, we will upload the invoice template to Appian as a document. To do this, navigate to `All Application Objects > DGS Knowledge Center > Artifacts`. Then click the `New` dropdown, and select `Document`. From there, select the template file from your file system, and upload it. When prompted to create a constant for the document, opt out unless you need to use a constant.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-40eade53da9f6b944cf07c02ea03e1ade8efb183%2F348861bbad376a3af611518cc55cdddce35c92f7-351x229.png?alt=media)

After uploading, you can click on the file in the Appian Designer to see the document ID for that document.

## Creating the site

We will now create a new site and interface in the Appian Designer. We will call this site `Invoice Viewer`. We will need to add a `Page`, and `Interface` to the site in order to get a UI to place WebViewer on. Once you add an interface, you will have to return to the previous tab/window to add the page to the site, and save the site.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-3822e012bd7738ed82adfc8e8c332f06d70dfb2b%2Fa4fb8799546f39e082daebabd2d5d47ea471cba3-724x676.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-8afebb03063bfd3c4052fddf938e29744f054fcc%2F3a04e3a15b8a580d5ae0913be4bd6ca40ea2ad75-725x677.png?alt=media)

On the interface page, we will use a simple one-column layout to start just to get WebViewer on the page. We can then add the Apryse WebViewer component into the section. If you are using your own custom page, add it where you would like it to be. Initially, we will get an error about the connected systems. We can fix this by providing the connected systems constant we created earlier. If done correctly, WebViewer should load, and display the UI.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-6f7026af9dfa43666268a2df6c4ec7087ea9aa10%2Ff0b4f4bbd531adec7e1e24c630b97e90de644a93-2061x995.png?alt=media)

With WebViewer loaded, we can now load the template we uploaded earlier. To do this, we can go back to the document in the `Artifacts` folder, click on it, and copy the document ID. We can then paste this document ID into the `appianDocId` property in the WebViewer component. If done correctly, the template should load in WebViewer.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-1630282bb4d43ef0b790c1b909a5fd57c8c81d40%2F8ceb49e2313319edde0a9c2e1292236c8db97c2c-724x491.png?alt=media)

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-d9b2b5310b367eee4f261f9827c8ffc613546cbb%2Fe9493aa78792e17f5e89cab94ea3c7b98ff7585f-1606x995.png?alt=media)

## Wiring up with expressions

To start, we will enter expression mode in the interface, and wrap the existing expressions in a `a!localVariables` function to add some variables to hold our data.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-d667da15b1bfbd5d9a13658b0720868ffa22185d%2F782d719cd4fe9b1fa17943944bf9a7fc78b9dc49-606x475.png?alt=media)

### Loading the invoice data

We need to get our invoice data from the database into a variable. To do this, we will use the `a!queryEntity` function to query the `Invoice` data store we created earlier. We will also need to set the `pagingInfo` parameter to retrieve one record. You can use your own logic to pick the correct record. We will then set the `data` variable to the first record in the data array.

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
local!invoice: a!queryEntity(
    entity: cons!DGS_Invoice_DS,
    query: a!query(
      selection: a!querySelection({
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.id',
          alias: "invoice_number",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.billTo',
          alias: "bill_to_name",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.shipTo',
          alias: "ship_to_number",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.subtotal',
          alias: "subtotal",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.salesTaxPercent',
          alias: "sales_t",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.salesTax',
          alias: "sales",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice.fields.total',
          alias: "total",
        ),
      }),
      pagingInfo: a!pagingInfo(
        startIndex: 1,
        batchSize: 1,
      )
    )
  ).data[1],
```

{% endcode %}
{% endtab %}
{% endtabs %}

Next, we will need another variable to hold the line items for the same invoice.

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
local!invoiceItems: a!queryEntity(
    entity: cons!DGS_InvoiceLineItems_DS,
    query: a!query(
      selection: a!querySelection({
        a!queryColumn(
          field: 'recordType!DGS Invoice Line Item.fields.description',
          alias: "description",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice Line Item.fields.unitPrice',
          alias: "unitPrice",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice Line Item.fields.qty',
          alias: "qty",
        ),
        a!queryColumn(
          field: 'recordType!DGS Invoice Line Item.fields.total',
          alias: "total",
        )
      }),
      filter: a!queryFilter(
        field: "invoiceId",
        operator: "=",
        value: local!invoice.invoice_number
      ),
      pagingInfo: a!pagingInfo(
        startIndex: 1,
        batchSize: -1,
      )
    )
  ).data,
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
The column names in the expressions have been altered for the guide to remove environment specific IDs. Please reference the respective column names via the record type in your environment.
{% endhint %}

The last thing we need to do before filling the template is to create the object to pass to the `templateData` property of the WebViewer component. This will be where we provide the data for the template. We can do this with the `a!update` function to merge the two pieces of data.

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
templateData: a!update(
  data: local!invoice,
  index: "items",
  value: local!invoiceItems
),
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Filling the template

Finally, if we refresh the interface page, or press `Test` near the top, we get...the unfilled template. What went wrong?

If you notice, the template does not have the values filled in. If you check the browser console, WebViewer should report an error about the `invoice_number` not being a string. This is due to the templating engine expecting a string, but the `invoice_number` field data is a number. This applies to the other numerical fields as well. To fix this, we will need to convert the numerical fields to strings.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-6658512c30358d2c1b92b56431de62bc888a188e%2F69ed10df2efd4db7a383a39d259eb60ce4caa5c7-907x113.png?alt=media)

To do this, all we have to do is change the numerical field types in the data types (`DGS_INVOICE`, and `DGS_INVOICE_LINE_ITEM`) to `Text` instead. This will then allow us to query the types as strings instead of numbers.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-58035e651dbd2aa4ad28fd3880e6447c72b0b91e%2F715bdc51f432b15d05e883affeebc5a8c72cca2a-1124x586.png?alt=media)

Once that is done, you can refresh the interface page, and the template should load with the data.

![](https://1373770520-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQBPkEFulYTrl1g37jENZ%2Fuploads%2Fgit-blob-436e4caa5f5f3a6d8f1f25ee7a207d52851d7677%2F3bbd0226f42d11c82895da42ab08b7ed2a8950bb-1605x921.png?alt=media)

That's it! You can now generate invoices in Appian using WebViewer. You can also use this same method to generate other documents such as contracts, reports, and more.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/appian/template-generation/sample-docgen-app.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
