Freemarker Reports

Overview

HTML reports generated with freemarker templates

Github: https://github.com/gitorko/project69

Freemarker

We will generate a single html file report using freemarker template and provide a rest url to download the report.

Code

 1package com.demo;
 2
 3import java.io.ByteArrayInputStream;
 4import java.io.StringWriter;
 5import java.util.Date;
 6import java.util.HashMap;
 7import java.util.List;
 8import java.util.Map;
 9import java.util.Random;
10import java.util.stream.Collectors;
11import java.util.stream.IntStream;
12
13import freemarker.template.Configuration;
14import freemarker.template.Template;
15import lombok.extern.slf4j.Slf4j;
16import org.springframework.core.io.InputStreamResource;
17import org.springframework.http.HttpHeaders;
18import org.springframework.http.MediaType;
19import org.springframework.http.ResponseEntity;
20import org.springframework.web.bind.annotation.GetMapping;
21import org.springframework.web.bind.annotation.RestController;
22
23@RestController
24@Slf4j
25public class HomeController {
26
27    @GetMapping("/report")
28    public ResponseEntity<InputStreamResource> getReport() throws Exception {
29        log.info("Generating report!");
30        String htmlReport = this.generateHtmlReport();
31        ByteArrayInputStream bis = new ByteArrayInputStream(htmlReport.getBytes());
32        return ResponseEntity.ok()
33                .contentType(MediaType.APPLICATION_OCTET_STREAM)
34                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"myreport.htm\"")
35                .body(new InputStreamResource(bis));
36    }
37
38    private String generateHtmlReport() throws Exception {
39        Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
40        cfg.setClassForTemplateLoading(this.getClass(), "/");
41        cfg.setDefaultEncoding("UTF-8");
42        Template template = cfg.getTemplate("templates/my-report.ftl");
43        List<Employee> employees = getEmployeeData();
44        Map<String, Object> templateData = new HashMap<>();
45        templateData.put("reportTitle", "Company Employee Report");
46        templateData.put("employees", employees);
47        StringWriter out = new StringWriter();
48        template.process(templateData, out);
49        return out.toString();
50    }
51
52    private List<Employee> getEmployeeData() {
53        //Sample Data
54        Random random = new Random();
55        return IntStream.range(0, 150)
56                .mapToObj(i -> Employee.builder()
57                        .name("Name " + i)
58                        .age(random.nextInt(65 - 20) + 20)
59                        .dob(new Date())
60                        .salary(40000 + (100000 - 40000) * random.nextDouble())
61                        .build())
62                .collect(Collectors.toList());
63    }
64}
 1<html>
 2
 3<head>
 4    <title>Employee Report</title>
 5    <style>
 6        table {
 7            font-family: arial, sans-serif;
 8            border-collapse: collapse;
 9            width: 100%;
10        }
11
12        td,
13        th {
14            border: 1px solid #DDDDDD;
15            text-align: left;
16            padding: 8px;
17        }
18
19        th {
20            background-color: #CCCCCC;
21        }
22
23        p.yellow {
24            color: #FFDC0B;
25            font-weight: bold;
26        }
27
28        p.green {
29            color: #2F8400;
30            font-weight: bold;
31        }
32    </style>
33</head>
34
35<body>
36<h3>${(reportTitle)!"Default Title"}</h3>
37<br/>
38
39<h4>Employee Details</h4>
40<table>
41    <tr>
42        <th>Id</th>
43        <th>Name</th>
44        <th>Age</th>
45        <th>Dob</th>
46        <th>Salary</th>
47    </tr>
48    <#assign empCounter=1>
49    <#list employees as empObj>
50        <tr>
51            <td>${empCounter}</td>
52            <td>
53                <a href="#">${empObj.name}</a>
54            </td>
55            <td>
56                ${empObj.age}
57            </td>
58            <td>
59                ${empObj.dob?date}
60            </td>
61            <td>
62                <#if empObj.salary gt 50000>
63                    <p class="green">
64                        ${empObj.salary}
65                    </p>
66                <#else>
67                    <p class="yellow">
68                        ${empObj.salary}
69                    </p>
70                </#if>
71            </td>
72        </tr>
73        <#assign empCounter=empCounter+1>
74    </#list>
75</table>
76<h2>Total Employees: ${employees?size}</h2>
77</body>
78</html>

Setup

 1# Project 69
 2
 3HTML reports with freemarker
 4
 5[https://gitorko.github.io/freemarker-reports/](https://gitorko.github.io/freemarker-reports/)
 6
 7### Version
 8
 9Check version
10
11```bash
12$java --version
13openjdk version "21.0.3" 2024-04-16 LTS
14```
15
16### Dev
17
18To run the backend in dev mode.
19
20```bash
21./gradlew clean build
22./gradlew bootRun
23```

References

https://freemarker.apache.org/

comments powered by Disqus