Ver código fonte

update jasper service

masarif 4 dias atrás
pai
commit
97f6ad271c

+ 7 - 0
pom.xml

@@ -72,6 +72,13 @@
 			<artifactId>kotlin-test-junit5</artifactId>
 			<scope>test</scope>
 		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
+		<dependency>
+			<groupId>net.sf.jasperreports</groupId>
+			<artifactId>jasperreports</artifactId>
+			<version>6.21.4</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 118 - 8
src/main/kotlin/co/id/datacomsolusindo/engineservice/report/ReportService.kt

@@ -1,15 +1,31 @@
 package co.id.datacomsolusindo.engineservice.report
 
+import net.sf.jasperreports.engine.*
+import net.sf.jasperreports.engine.export.FileHtmlResourceHandler
+import net.sf.jasperreports.engine.export.HtmlExporter
+import net.sf.jasperreports.engine.export.JRCsvExporter
+import net.sf.jasperreports.engine.export.JRPdfExporter
+import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter
+import net.sf.jasperreports.engine.fill.JRSwapFileVirtualizer
+import net.sf.jasperreports.engine.util.FileBufferedOutputStream
+import net.sf.jasperreports.engine.util.JRSwapFile
+import net.sf.jasperreports.export.*
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.beans.factory.annotation.Value
-import org.springframework.core.annotation.Order
-import org.springframework.stereotype.Service
 import java.io.File
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
 import java.nio.file.Files
+import java.nio.file.Path
 import java.nio.file.Paths
 import java.nio.file.StandardCopyOption
+import java.sql.DriverManager
+import java.util.UUID
+import java.util.zip.ZipEntry
+import java.util.zip.ZipOutputStream
 
-class ReportService(rptService: RptService) {
+class ReportService(val rptService: RptService) {
 
     @Value("\${spring.datasource.url}")
     lateinit var jdbcUrl: String
@@ -26,8 +42,6 @@ class ReportService(rptService: RptService) {
     private val projectDir = System.getProperty("user.dir")
     private val pathResult = "$projectDir/${rptService.pathResult}"
     private val pathPreview = "$projectDir/${rptService.pathPreview}"
-//    private val pathResult = "$projectDir/result"
-//    private val pathPreview = "$projectDir/preview"
 
     private val logger = ReportLogger.getLogger(this::class.java)
 
@@ -62,7 +76,7 @@ class ReportService(rptService: RptService) {
 
     }
 
-    private fun generateReport(params: MutableMap<String, Any>, isPreview: Boolean = false): ByteArray? {
+    private fun generateReport(params: MutableMap<String, Any>, isPreview: Boolean = false): InputStream? {
         val userSubmitted = params["userSubmitted"].toString()
         val reportJob = ReportJob(userSubmitted = userSubmitted, criteria = U.mapper.writeValueAsString(params))
         val exist = reportJobRepository.findByJobKeyAndUserSubmitted(reportJob.jobKey, reportJob.userSubmitted)
@@ -81,14 +95,110 @@ class ReportService(rptService: RptService) {
             } else null
         } else null
 
-        return existReport?.readBytes()?.let {
+        return existReport?.inputStream()?.let {
             // update reportJob
+            val rpt = exist.get()
             it
         } ?: run {
-            null
+            val templateFile = "${rptService.pathTemplate}/${params["templateName"]}"
+            val jasperReport = JasperCompileManager.compileReport(templateFile.byteInputStream())
+            generateReportFile(jasperReport, formatType, params)
         }
 
     }
 
+    private fun generateReportFile(
+        jasperReport: JasperReport,
+        formatType: FormatType,
+        paramReport: MutableMap<String, Any>
+    ): InputStream? {
+        val os = FileBufferedOutputStream()
+
+        DriverManager.getConnection(jdbcUrl, dbUser, dbPass).use { connection ->
+            try {
+                val jasperPrint = JasperFillManager.fillReport(jasperReport, paramReport, connection)
+                val unique = UUID.randomUUID().toString()
+                val tmpDir = "report/swap"
+                File(tmpDir).mkdirs()
+                val vrt = JRSwapFile(tmpDir, 1024, 1024)
+                val reportVirT: JRVirtualizer = JRSwapFileVirtualizer(10, vrt, true)
+                paramReport[JRParameter.REPORT_VIRTUALIZER] = reportVirT
+
+                val exporter = when (formatType) {
+                    FormatType.PDF, FormatType.SCREEN -> {
+                        val exporter = JRPdfExporter()
+                        exporter.exporterOutput = SimpleOutputStreamExporterOutput(os)
+                        exporter
+                    }
+                    FormatType.CSV -> {
+                        val cs = SimpleCsvExporterConfiguration()
+                        cs.forceFieldEnclosure = true
+                        cs.isWriteBOM = true // For UTF-8 BOM
+                        cs.fieldDelimiter = "," // Bisa juga pakai ; kalau regional
+                        val csvExporter = JRCsvExporter()
+                        csvExporter.setConfiguration(cs)
+                        csvExporter.exporterOutput = SimpleWriterExporterOutput(os)
+                        csvExporter
+                    }
+                    FormatType.XLSX -> {
+                        val exporter = JRXlsxExporter()
+                        exporter.exporterOutput = SimpleOutputStreamExporterOutput(os)
+                        exporter
+                    }
+                    FormatType.HTML -> {
+                        if (!File(".tmp/$unique").exists()) {
+                            File(".tmp/$unique").mkdirs()
+                        }
+                        //reportGenerateId
+                        val file = File(".tmp/$unique/${paramReport["templateName"]}.html")
+                        val htmlExp = HtmlExporter()
+                        val configuration = SimpleHtmlExporterConfiguration()
+                        htmlExp.setConfiguration(configuration)
+
+                        val exporterOutput = SimpleHtmlExporterOutput(file)
+                        val resourcesDir = File(file.parent, file.name.toString() + "_images")
+                        val pathPattern = resourcesDir.name + "/{0}"
+                        exporterOutput.imageHandler = FileHtmlResourceHandler(resourcesDir, pathPattern)
+                        htmlExp.exporterOutput = exporterOutput
+                        htmlExp
+                    }
+                }
+
+                exporter.setExporterInput(SimpleExporterInput(jasperPrint))
+                exporter.exportReport()
+                if (formatType == FormatType.HTML) {
+                    pack(".tmp/$unique", os)
+                }
+                return os.dataInputStream
+            } catch (e: Exception) {
+                logger.error("failed to generate report", e);
+                throw (e)
+            } finally {
+                os.flush()
+                os.close()
+            }
+        }
+    }
+
+    private fun pack(sourceDirPath: String, os: OutputStream): OutputStream {
+        ZipOutputStream(os).use { zs ->
+            val pp: Path = Paths.get(sourceDirPath)
+            Files.walk(pp)
+                .filter { path -> !Files.isDirectory(path) }
+                .forEach { path ->
+                    val zipEntry = ZipEntry(pp.relativize(path).toString())
+                    try {
+                        zs.putNextEntry(zipEntry)
+                        Files.copy(path, zs)
+                        zs.closeEntry()
+                    } catch (e: IOException) {
+                        logger.error("failed zip pack", e)
+                    }
+                }
+        }
+
+        return os
+    }
+
 
 }