See all tutorials

Tutorials » Email attachments, invoice attachment example

Many times the emails generated by web applications will need to contain dynamic files as attachments. One of such example might be an email with an invoice order PDF file as attachment. The email body can contain the same dynamic content as the one from the attached PDF file.

Webpagebytes CMS allows a web application to manage the content of the email body and also the content of the attachments as templates.

This tutorial will use concepts presented in two previous tutorials, generate dynamic PDF documents and generate dynamic email templates.

To attach dynamic content files to an email template take the following tasks:

Create a site page with the email body template

Step 1

In Webpagebytes CMS administration interface navigate to Site pages section and create a new record with the below content. The content mix static HTML with Freemarker scripting to produce an email body about the invoice order.

<html>
<head>
   <meta charset="UTF-8">
</head>
<body>
    <div style="padding 10px 0;">Hi ${wpbAppModel["name"]},</div>
    <div> This email body contains an invoice example generated with Webpagebytes CMS. The same invoice is attached in a PDF file. </div>
    <div style="padding: 5px; background-color: #FAFAFA; margin: 10px 0;">
    <div style="border-bottom: 1px solid #009F00; font-size: 1.5em; margin: 10px 0 5px; color: #009F00;"> Invoice example </div>
    <div style="margin-bottom: 5px;"> Invoice# ${wpbAppModel["invoice_no"]?string.computer}. Date: ${wpbAppModel["today"]?date} </div>
    <div style="margin: 15px 0px;">
        [COMPANY NAME] <br>
        [Address] <br>
        [Website]
    </div>

    <div style="margin: 10px 0;">
        <table>
        <tr> 
            <th style="padding: 5px 3px; background-color: #FFF1A5; width: 240px; text-align:left;"> To: </th> 
            <th style="padding: 5px 3px; background-color: #FFF1A5; width: 240px; text-align:left;"> Ship to:</th> 
        </tr>
        <tr> 
            <td> Name: ${wpbAppModel["name"]} </td> <td> Name: ${wpbAppModel["name"]} </td> 
        </tr>
        <tr> 
            <td> Address: ${wpbAppModel["address"]} </td> <td> Address: ${wpbAppModel["address"]}</td> 
        </tr>
        <tr> 
            <td> Tel: ${wpbAppModel["telephone"]} </td> <td> Tel: ${wpbAppModel["telephone"]} </td> 
        </tr>
        </table>
    </div>
    <div>
    <table style="border: 1px solid #DFDFDF; border-collapse:collapse;">
    <tr> 
        <th style="width:50px;text-align: left; background-color: #DFDFDF; padding: 3px 10px;"> Item # </th> 
        <th style="width:150px; text-align: left; background-color: #DFDFDF; padding: 3px 10px;"> Description </th>
        <th style="width:100px; text-align: left; background-color: #DFDFDF; padding: 3px 10px;"> QTY </th> 
        <th style="width:100px; text-align: left; background-color: #DFDFDF; padding: 3px 10px;"> Unit price </th> 
        <th style="width:100px; text-align: left; background-color: #DFDFDF; padding: 3px 10px;"> Line total </th> 
    </tr>
    <#assign products=wpbAppModel["products"] />
    <#assign total=0 />
    <#list products as item>
    <tr> 
        <td style="padding: 3px 10px;"> ${item_index+1} </td> 
        <td style="padding: 3px 10px;"> ${item.name} </td> 
        <td style="padding: 3px 10px;"> ${item.quantity} </td> 
        <td style="padding: 3px 10px;"> ${item.price?string.currency} </td> 
        <td style="padding: 3px 10px;"> ${(item.price*item.quantity)?string.currency} </td> 
    </tr>
    <#assign total=(total + item.price*item.quantity) />
    </#list>
    </table>

    <table style="border-collapse:collapse;">
    <tr> 
        <td style="width:50px;   padding: 3px 10px;"> </td> 
        <td style="width:150px;  padding: 3px 10px;"> </td> 
        <td style="width:100px;  padding: 3px 10px;"> </td> 
        <td style="width:100px;  padding: 3px 10px;"> Total: </td> 
        <td style="width:100px;  padding: 3px 10px;font-weight: bold;"> ${total?string.currency} </td> 
    </tr>
    </table>
    </div>
    </div>
</body>
</html>

Create a site page with the attachment template

Step 2

The attachment PDF will be generated with Apache FOP and will require XLS-FO content to produce the PDF file. The dynamic XLS-FO content will be generated by Webpagebytes CMS from a site page.

The site page content is the same as the one from a previous tutorial XLS-FO content for an invoice PDF

Add dynamic data to the application model

Step 3

Webpagebytes CMS will need the invoice dynamic data to be added to the application model in order to generate the content. The code is common with the controller presented in a previous tutorial on how to include a QR code image in a PDF file.

Note that the keys added to the application model are used in the Freemarker script at Step 1 and Step 2.

public void handleRequest(HttpServletRequest request,
                          HttpServletResponse response, 
                          WPBModel model, 
                          WPBForward forward) throws WPBException 
{
...
model.getCmsApplicationModel().put("today", new Date());        
model.getCmsApplicationModel().put("invoice_no", 475443);        
model.getCmsApplicationModel().put("name", "rgbdgc");
model.getCmsApplicationModel().put("telephone", "555-1545");
model.getCmsApplicationModel().put("address", "234 Park Avenue 65234");        
model.getCmsApplicationModel().put("invoiceQR", base64QRCode("http://www.webpagebytes.com/invoice-example/475443"));        


ArrayList<Map<String, Object>> products = new ArrayList<Map<String,Object>>();
Map<String, Object> product1 = new HashMap<String, Object>();
product1.put("name", "Milk");
product1.put("quantity", 62);
product1.put("price", 375);
products.add(product1);

Map<String, Object> product2 = new HashMap<String, Object>();
product2.put("name", "Tea");
product2.put("quantity", 84);
product2.put("price", 445);
products.add(product2);

model.getCmsApplicationModel().put("products", products);
...
}

Fetch the email body and the attachment content and send it via an email server

Step 4

The email body content and the XLS-FO used to generate the attached PDF file can be fetched using WPBContentProvider interface as presented in a previous tutorial on how to create a simple email body template.

The below image represents the email body and the PDF attachment generated by this tutorial (using a GMail account).
email and attachment PDF generated with Webpagebytes CMS

Fork me on GitHub