diff --git a/spring-jasper-example/README.md b/spring-jasper-example/README.md index 2956a49..e03d3fd 100644 --- a/spring-jasper-example/README.md +++ b/spring-jasper-example/README.md @@ -19,6 +19,7 @@ Includes loading `.jasper` templates, populating them with mock data, and export ## Profiles you can activate -- **client-list-dev** – Used in Docker, in the future, it will use pre-compiled `.jasper` files instead of `.jrxml`. Activates the internal module that generates a simple client report. +- **client-list-dev** – Used in Docker, Activates the internal module that generates a simple client report. - **client-list-local** – Used locally, activates the internal module that generates a simple client report and use `.jrxml`. - +- **bill-dev** – Used in Docker, Activates the internal module that generates a simple bill report. +- **bill-local** – Used locally, activates the internal module that generates a simple bill report and use `.jrxml`. diff --git a/spring-jasper-example/src/main/java/com/io/example/base/JasperReader.java b/spring-jasper-example/src/main/java/com/io/example/base/JasperReader.java new file mode 100644 index 0000000..8227a73 --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/base/JasperReader.java @@ -0,0 +1,37 @@ +package com.io.example.base; + +import net.sf.jasperreports.engine.*; +import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; +import net.sf.jasperreports.engine.util.JRLoader; +import org.springframework.core.io.ClassPathResource; + +import java.io.InputStream; +import java.util.Collection; +import java.util.HashMap; + +public class JasperReader { + + public static byte[] exportReportJrxmlToPdf(Collection beanCollection, String path){ + try { + InputStream stream = new ClassPathResource(path).getInputStream(); + JasperReport jasperReport = JasperCompileManager.compileReport(stream); + JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(beanCollection); + JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource); + return JasperExportManager.exportReportToPdf(jasperPrint); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static byte[] exportReportJasperToPdf(Collection beanCollection, String path){ + try (InputStream stream = new ClassPathResource(path).getInputStream()) { + JasperReport jasperReport = (JasperReport) JRLoader.loadObject(stream); + JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(beanCollection); + JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource); + return JasperExportManager.exportReportToPdf(jasperPrint); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/controller/ReportController.java b/spring-jasper-example/src/main/java/com/io/example/clientList/controller/ClientsController.java similarity index 78% rename from spring-jasper-example/src/main/java/com/io/example/clientList/controller/ReportController.java rename to spring-jasper-example/src/main/java/com/io/example/clientList/controller/ClientsController.java index 494a9fb..4abf9a9 100644 --- a/spring-jasper-example/src/main/java/com/io/example/clientList/controller/ReportController.java +++ b/spring-jasper-example/src/main/java/com/io/example/clientList/controller/ClientsController.java @@ -1,6 +1,6 @@ package com.io.example.clientList.controller; -import com.io.example.clientList.service.ReportService; +import com.io.example.clientList.service.ClientsReportService; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpHeaders; @@ -12,13 +12,13 @@ @RestController @Profile({"client-list-dev", "client-list-local"}) @RequiredArgsConstructor -public class ReportController { +public class ClientsController { - private final ReportService reportService; + private final ClientsReportService clientsReportService; @GetMapping("/reports/clients") public ResponseEntity getClientsReport() { - byte[] pdf = this.reportService.generateClientReport(); + byte[] pdf = this.clientsReportService.generateClientsPdf(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=clients.pdf") .contentType(MediaType.APPLICATION_PDF) diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportDevServiceImpl.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportDevServiceImpl.java new file mode 100644 index 0000000..e5dbaa7 --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportDevServiceImpl.java @@ -0,0 +1,26 @@ +package com.io.example.clientList.service; + +import com.io.example.clientList.dto.ClientDto; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import java.util.*; + +import static com.io.example.base.JasperReader.exportReportJasperToPdf; + +@Service +@Profile({"client-list-dev"}) +public class ClientsReportDevServiceImpl implements ClientsReportService { + + private static final List clients = Arrays.asList( + new ClientDto(1, "Alice", "Brazil"), + new ClientDto(2, "Bob", "USA"), + new ClientDto(3, "Carlos", "Spain") + ); + + @Override + public byte[] generateClientsPdf() { + return exportReportJasperToPdf(clients, "reports/client-list-template.jasper"); + } + + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportLocalServiceImpl.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportLocalServiceImpl.java new file mode 100644 index 0000000..cbd5ac7 --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportLocalServiceImpl.java @@ -0,0 +1,25 @@ +package com.io.example.clientList.service; + +import com.io.example.clientList.dto.ClientDto; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import java.util.*; + +import static com.io.example.base.JasperReader.exportReportJrxmlToPdf; + +@Service +@Profile({"client-list-local"}) +public class ClientsReportLocalServiceImpl implements ClientsReportService { + + private static final List clients = Arrays.asList( + new ClientDto(1, "Alice", "Brazil"), + new ClientDto(2, "Bob", "USA"), + new ClientDto(3, "Carlos", "Spain") + ); + + @Override + public byte[] generateClientsPdf() { + return exportReportJrxmlToPdf(clients, "reports/client-list-template.jrxml"); + } + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportService.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportService.java new file mode 100644 index 0000000..97260ca --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ClientsReportService.java @@ -0,0 +1,5 @@ +package com.io.example.clientList.service; + +public interface ClientsReportService { + byte[] generateClientsPdf(); +} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportDevService.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportDevService.java deleted file mode 100644 index af9d4e5..0000000 --- a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportDevService.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.io.example.clientList.service; - -import com.io.example.clientList.dto.ClientDto; -import net.sf.jasperreports.engine.*; -import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.ClassPathResource; -import org.springframework.stereotype.Service; - -import java.io.InputStream; -import java.util.*; - -@Service -@Profile({"client-list-dev"}) -public class ReportDevService implements ReportService { - - private static final List clients = Arrays.asList( - new ClientDto(1, "Alice", "Brazil"), - new ClientDto(2, "Bob", "USA"), - new ClientDto(3, "Carlos", "Spain") - ); - - @Override - public byte[] generateClientReport() { - return this.exportReportToPdf(); - } - - /* - * TODO: In the future, this should be migrated to use: - * - * InputStream stream = new ClassPathResource("reports/client-list.jasper").getInputStream(); - * JasperReport jasperReport = (JasperReport) JRLoader.loadObject(stream); - * - * This approach is the recommended way in production environments. - */ - - private byte[] exportReportToPdf(){ - try { - InputStream stream = new ClassPathResource("reports/client-list.jrxml").getInputStream(); - JasperReport jasperReport = JasperCompileManager.compileReport(stream); - JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(clients); - JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource); - return JasperExportManager.exportReportToPdf(jasperPrint); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportLocalService.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportLocalService.java deleted file mode 100644 index bf8b2ab..0000000 --- a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportLocalService.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.io.example.clientList.service; - -import com.io.example.clientList.dto.ClientDto; -import net.sf.jasperreports.engine.*; -import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.ClassPathResource; -import org.springframework.stereotype.Service; -import java.io.InputStream; -import java.util.*; - -@Service -@Profile({"client-list-local"}) -public class ReportLocalService implements ReportService { - - private static final List clients = Arrays.asList( - new ClientDto(1, "Alice", "Brazil"), - new ClientDto(2, "Bob", "USA"), - new ClientDto(3, "Carlos", "Spain") - ); - - @Override - public byte[] generateClientReport() { - return this.exportReportToPdf(); - } - - private byte[] exportReportToPdf(){ - try { - InputStream stream = new ClassPathResource("reports/client-list.jrxml").getInputStream(); - JasperReport jasperReport = JasperCompileManager.compileReport(stream); - JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(clients); - JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource); - return JasperExportManager.exportReportToPdf(jasperPrint); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportService.java b/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportService.java deleted file mode 100644 index 31ce34d..0000000 --- a/spring-jasper-example/src/main/java/com/io/example/clientList/service/ReportService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.io.example.clientList.service; - -public interface ReportService { - byte[] generateClientReport(); -} diff --git a/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/controller/BillController.java b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/controller/BillController.java new file mode 100644 index 0000000..688e398 --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/controller/BillController.java @@ -0,0 +1,29 @@ +package com.io.example.dataUsageBill.controller; + +import com.io.example.clientList.service.ClientsReportService; +import com.io.example.dataUsageBill.service.BillReportService; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Profile({"bill-dev", "bill-local"}) +@RequiredArgsConstructor +public class BillController { + + private final BillReportService billReportService; + + @GetMapping("/reports/bill") + public ResponseEntity getBillData() { + byte[] pdf = this.billReportService.generateBillPdf(); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=bill.pdf") + .contentType(MediaType.APPLICATION_PDF) + .body(pdf); + } + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/dto/BillDto.java b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/dto/BillDto.java new file mode 100644 index 0000000..ed1c042 --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/dto/BillDto.java @@ -0,0 +1,37 @@ +package com.io.example.dataUsageBill.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BillDto { + private String orgName; + private String depName; + private String devName; + private String groupName; + private String dayStart; + private String dayEnd; + + private Integer dtoOM; + private Integer dtoON; + private Integer dtoOL; + private Integer dtoDL; + private Integer dtoDN; + private Integer dtoD; + + private Integer dtoOMamount; + private Integer dtoONamount; + private Integer dtoOLamount; + private Integer dtoDLamount; + private Integer dtoDNamount; + private Integer dtoDamount; + + private Integer totalHrs; + private Integer toltalAm; + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportDevServiceImpl.java b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportDevServiceImpl.java new file mode 100644 index 0000000..864c6bd --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportDevServiceImpl.java @@ -0,0 +1,46 @@ +package com.io.example.dataUsageBill.service; + +import com.io.example.dataUsageBill.dto.BillDto; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static com.io.example.base.JasperReader.exportReportJasperToPdf; + +@Service +@Profile({"bill-dev"}) +public class BillReportDevServiceImpl implements BillReportService { + + @Override + public byte[] generateBillPdf() { + return exportReportJasperToPdf(getBillDto(), "reports/bill-template.jasper"); + } + + private List getBillDto(){ + BillDto bill = BillDto.builder() + .orgName("My Organization") + .depName("IT Department") + .devName("Development Team") + .groupName("Network Group") + .dayStart("2025-08-01") + .dayEnd("2025-08-31") + .dtoOM(10) + .dtoON(5) + .dtoOL(3) + .dtoDL(7) + .dtoDN(2) + .dtoD(1) + .dtoOMamount(100) + .dtoONamount(50) + .dtoOLamount(30) + .dtoDLamount(70) + .dtoDNamount(20) + .dtoDamount(10) + .totalHrs(28) + .toltalAm(280) + .build(); + return List.of(bill); + } + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportLocalServiceImpl.java b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportLocalServiceImpl.java new file mode 100644 index 0000000..49dac8a --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportLocalServiceImpl.java @@ -0,0 +1,46 @@ +package com.io.example.dataUsageBill.service; + +import com.io.example.dataUsageBill.dto.BillDto; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static com.io.example.base.JasperReader.exportReportJrxmlToPdf; + +@Service +@Profile({"bill-local"}) +public class BillReportLocalServiceImpl implements BillReportService { + + @Override + public byte[] generateBillPdf() { + return exportReportJrxmlToPdf(getBillDto(), "reports/bill-template.jrxml"); + } + + private List getBillDto(){ + BillDto bill = BillDto.builder() + .orgName("My Organization") + .depName("IT Department") + .devName("Development Team") + .groupName("Network Group") + .dayStart("2025-08-01") + .dayEnd("2025-08-31") + .dtoOM(10) + .dtoON(5) + .dtoOL(3) + .dtoDL(7) + .dtoDN(2) + .dtoD(1) + .dtoOMamount(100) + .dtoONamount(50) + .dtoOLamount(30) + .dtoDLamount(70) + .dtoDNamount(20) + .dtoDamount(10) + .totalHrs(28) + .toltalAm(280) + .build(); + return List.of(bill); + } + +} diff --git a/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportService.java b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportService.java new file mode 100644 index 0000000..f88db2b --- /dev/null +++ b/spring-jasper-example/src/main/java/com/io/example/dataUsageBill/service/BillReportService.java @@ -0,0 +1,5 @@ +package com.io.example.dataUsageBill.service; + +public interface BillReportService { + byte[] generateBillPdf(); +} diff --git a/spring-jasper-example/src/main/resources/application-bill-dev.yml b/spring-jasper-example/src/main/resources/application-bill-dev.yml new file mode 100644 index 0000000..769c151 --- /dev/null +++ b/spring-jasper-example/src/main/resources/application-bill-dev.yml @@ -0,0 +1,7 @@ +server: + port: ${SERVER_PORT:8084} + +spring: + + application: + name: spring-jasper-example-bill-dev \ No newline at end of file diff --git a/spring-jasper-example/src/main/resources/application-bill-local.yml b/spring-jasper-example/src/main/resources/application-bill-local.yml new file mode 100644 index 0000000..8db22d9 --- /dev/null +++ b/spring-jasper-example/src/main/resources/application-bill-local.yml @@ -0,0 +1,7 @@ +server: + port: ${SERVER_PORT:8083} + +spring: + + application: + name: spring-jasper-example-bill-local \ No newline at end of file diff --git a/spring-jasper-example/src/main/resources/application-client-list-local.yml b/spring-jasper-example/src/main/resources/application-client-list-local.yml index 872bdd1..ac6e66f 100644 --- a/spring-jasper-example/src/main/resources/application-client-list-local.yml +++ b/spring-jasper-example/src/main/resources/application-client-list-local.yml @@ -4,4 +4,4 @@ server: spring: application: - name: spring-jasper-exampleclient-list-local \ No newline at end of file + name: spring-jasper-example-client-list-local \ No newline at end of file diff --git a/spring-jasper-example/src/main/resources/reports/bill-template.jasper b/spring-jasper-example/src/main/resources/reports/bill-template.jasper new file mode 100644 index 0000000..f1f57b8 Binary files /dev/null and b/spring-jasper-example/src/main/resources/reports/bill-template.jasper differ diff --git a/spring-jasper-example/src/main/resources/reports/bill-template.jrxml b/spring-jasper-example/src/main/resources/reports/bill-template.jrxml new file mode 100644 index 0000000..bf688d2 --- /dev/null +++ b/spring-jasper-example/src/main/resources/reports/bill-template.jrxml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <element kind="rectangle" uuid="50312856-42b0-43f4-9483-06d8fe503412" mode="Opaque" x="-1" y="56" width="329" height="100" forecolor="#D9D7E0" backcolor="#D9D7E0" radius="15"/> + <element kind="staticText" uuid="fbf42f07-8a0a-4f7f-a7d9-1b325c83670f" stretchType="ElementGroupHeight" x="60" y="10" width="90" height="40" fontSize="26.0" bold="true"> + <text><![CDATA[LOGO]]></text> + </element> + <element kind="staticText" uuid="8c715988-6da5-4761-a9b0-f04b284f39e7" x="240" y="-10" width="70" height="20" forecolor="#525252" fontSize="12.0" bold="true"> + <text><![CDATA[INVOICE]]></text> + <box leftPadding="10"/> + </element> + <element kind="staticText" uuid="3ee170a9-03ed-4539-bc81-4edd6ebfbc29" x="20" y="70" width="100" height="20"> + <text><![CDATA[Organization Name]]></text> + </element> + <element kind="staticText" uuid="c7dfbb91-16e7-4a72-b7dd-852c724ea867" x="20" y="90" width="100" height="20"> + <text><![CDATA[Department Name]]></text> + </element> + <element kind="staticText" uuid="267f032d-a98a-4177-b5b9-757dba3a7a27" x="20" y="110" width="100" height="20"> + <text><![CDATA[Devision Name]]></text> + </element> + <element kind="staticText" uuid="eb345a07-991c-4aba-9088-e71e38237921" x="20" y="130" width="100" height="20"> + <text><![CDATA[Group Name]]></text> + </element> + <element kind="staticText" uuid="0ea065e5-47b1-4a21-8189-172cc1a9fe8b" x="210" y="10" width="60" height="13"> + <text><![CDATA[Invoice Date:]]></text> + </element> + <element kind="textField" uuid="fed3f44e-c42d-4e85-8eb3-7a6d405e07ec" x="270" y="10" width="100" height="13" fontSize="10.0" pattern="MMMMM dd, yyyy"> + <expression><![CDATA[new java.util.Date()]]></expression> + </element> + <element kind="textField" uuid="70a5b8dc-2c16-413f-af39-93f36a8689b8" x="170" y="70" width="180" height="19"> + <expression><![CDATA[$F{orgName}]]></expression> + </element> + <element kind="textField" uuid="0e07e32e-62ef-40d9-ba1e-d5b1e757a2b5" x="170" y="90" width="180" height="21"> + <expression><![CDATA[$F{depName}]]></expression> + </element> + <element kind="textField" uuid="fb083231-e511-4c79-af82-4fa2549cba04" x="170" y="130" width="180" height="20"> + <expression><![CDATA[$F{devName}]]></expression> + </element> + <element kind="textField" uuid="4106684d-ae0b-4bcd-b1fd-02cd6dda7478" x="170" y="110" width="180" height="20"> + <expression><![CDATA[$F{groupName}]]></expression> + </element> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-jasper-example/src/main/resources/reports/client-list-template.jasper b/spring-jasper-example/src/main/resources/reports/client-list-template.jasper new file mode 100644 index 0000000..3ca1f8e Binary files /dev/null and b/spring-jasper-example/src/main/resources/reports/client-list-template.jasper differ diff --git a/spring-jasper-example/src/main/resources/reports/client-list.jrxml b/spring-jasper-example/src/main/resources/reports/client-list-template.jrxml similarity index 100% rename from spring-jasper-example/src/main/resources/reports/client-list.jrxml rename to spring-jasper-example/src/main/resources/reports/client-list-template.jrxml