Last active
December 31, 2021 02:50
-
-
Save jeffque/6fe3386982b00fe7ed5a3d2ac499bf0d to your computer and use it in GitHub Desktop.
Compilação recursiva jasper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package br.com.softsite.relatorioservice.relatorio; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import net.sf.jasperreports.engine.JRException; | |
| import net.sf.jasperreports.engine.JasperCompileManager; | |
| import net.sf.jasperreports.engine.JasperReport; | |
| import net.sf.jasperreports.engine.util.JRLoader; | |
| import net.sf.jasperreports.engine.util.JRSaver; | |
| class Compilacao { | |
| private final Path jrxml; | |
| private final Path jasper; | |
| private JasperReport jasperReport; | |
| Compilacao(Path base, String relatJrxml) { | |
| this.jrxml = base.resolve(relatJrxml); | |
| this.jasper = base.resolve(toJasper(relatJrxml)); | |
| } | |
| JasperReport getReport() throws JRException, IOException { | |
| if (condicaoParaCompilacao()) { | |
| // ok, tá na hora de criar... | |
| return compila(); | |
| } else if (jasperReport == null) { | |
| if (!Files.exists(jasper)) { | |
| return null; | |
| } | |
| if (jasperReport != null) { | |
| return jasperReport; | |
| } | |
| synchronized (this) { | |
| if (jasperReport != null) { | |
| return jasperReport; | |
| } | |
| return jasperReport = (JasperReport) JRLoader.loadObject(jasper.toFile()); | |
| } | |
| } | |
| return jasperReport; | |
| } | |
| private JasperReport compila() throws IOException, JRException { | |
| if (!condicaoParaCompilacao()) { | |
| if (jasperReport != null) { | |
| return jasperReport; | |
| } | |
| } | |
| synchronized (this) { | |
| if (!condicaoParaCompilacao()) { | |
| if (jasperReport != null) { | |
| return jasperReport; | |
| } | |
| } | |
| try (InputStream reportStream = Files.newInputStream(jrxml)) { | |
| jasperReport = JasperCompileManager.compileReport(reportStream); | |
| JRSaver.saveObject(jasperReport, jasper.toFile()); | |
| return jasperReport; | |
| } | |
| } | |
| } | |
| private boolean condicaoParaCompilacao() throws IOException { | |
| return !Files.exists(jasper) || Files.getLastModifiedTime(jasper).compareTo(Files.getLastModifiedTime(jrxml)) < 0; | |
| } | |
| private static String toJasper(String jrxml) { | |
| return jrxml.replaceFirst("\\.jrxml$", ".jasper"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package br.com.softsite.relatorioservice.relatorio; | |
| import java.io.File; | |
| import java.io.IOException; | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import java.util.Collections; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.stream.Stream; | |
| import org.springframework.stereotype.Component; | |
| import net.sf.jasperreports.engine.JRChild; | |
| import net.sf.jasperreports.engine.JRElementGroup; | |
| import net.sf.jasperreports.engine.JRException; | |
| import net.sf.jasperreports.engine.JasperReport; | |
| import net.sf.jasperreports.engine.base.JRBaseSubreport; | |
| @Component | |
| public class CompileJasperRecursive { | |
| private final Map<Path, Compilacao> mapeamento = Collections.synchronizedMap(new HashMap<>()); | |
| public JasperReport getJasperReport(String pathToJrxmlStr, String jrxml) throws IOException, JRException { | |
| return compileIfShould(new File(pathToJrxmlStr).toPath(), jrxml); | |
| } | |
| private JasperReport compileIfShould(Path pathToJrxml, String jrxml) throws IOException, JRException { | |
| Path jrxmlSrc = pathToJrxml.resolve(jrxml); | |
| if (!Files.exists(jrxmlSrc)) { | |
| throw new IOException("Sem relatório " + jrxmlSrc.toAbsolutePath() + " =("); | |
| } | |
| Compilacao comp = mapeamento.computeIfAbsent(pathToJrxml.resolve(jrxml), __ -> new Compilacao(pathToJrxml, jrxml)); | |
| JasperReport jasperReport = comp.getReport(); | |
| if (jasperReport != null) { | |
| try { | |
| Stream.of(jasperReport.getAllBands()).flatMap(this::explodeChildren).filter(child -> child instanceof JRBaseSubreport).map(JRBaseSubreport.class::cast).forEach(c -> verificaFilhos(c, pathToJrxml)); | |
| } catch (WrappedJRException e) { | |
| e.throwInner(); | |
| } | |
| } | |
| return jasperReport; | |
| } | |
| private Stream<JRChild> explodeChildren(JRElementGroup element) { | |
| return element.getChildren().stream().flatMap(el -> { | |
| Stream<JRChild> stream = Stream.of(el); | |
| if (el instanceof JRElementGroup) { | |
| stream = Stream.concat(stream, explodeChildren((JRElementGroup) el)); | |
| } | |
| return stream; | |
| }); | |
| } | |
| private void verificaFilhos(JRBaseSubreport subRepo, Path path) { | |
| String expression = subRepo.getExpression().getText(); | |
| if (expression.contains(".jasper")) { | |
| System.out.println("pegou do text " + expression); | |
| String subRepoJrxml = textBaseRubRepo2jrxml(expression); | |
| try { | |
| compileIfShould(path, subRepoJrxml); | |
| } catch (IOException e) { | |
| throw new WrappedJRException(e); | |
| } catch (JRException e) { | |
| throw new WrappedJRException(e); | |
| } | |
| } | |
| } | |
| private String textBaseRubRepo2jrxml(String subRepoText) { | |
| return subRepoText.replaceAll("^.*\"[\\\\/]*([^.]*)\\.jasper\".*$", "$1.jrxml"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package br.com.softsite.relatorioservice; | |
| import java.io.IOException; | |
| import java.io.OutputStream; | |
| import java.sql.Connection; | |
| import java.sql.SQLException; | |
| import java.util.HashMap; | |
| import java.util.Locale; | |
| import java.util.Map; | |
| import java.util.function.Supplier; | |
| import javax.servlet.http.HttpServletRequest; | |
| import javax.servlet.http.HttpServletResponse; | |
| import org.slf4j.Logger; | |
| import org.slf4j.LoggerFactory; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| import org.springframework.http.HttpStatus; | |
| import org.springframework.util.MultiValueMap; | |
| import org.springframework.web.bind.annotation.ExceptionHandler; | |
| import org.springframework.web.bind.annotation.PathVariable; | |
| import org.springframework.web.bind.annotation.RequestMapping; | |
| import org.springframework.web.bind.annotation.RequestMethod; | |
| import org.springframework.web.bind.annotation.RequestParam; | |
| import org.springframework.web.bind.annotation.ResponseStatus; | |
| import org.springframework.web.bind.annotation.RestController; | |
| import com.google.common.base.Throwables; | |
| import br.com.softsite.hikarigs.TenantRoutingDataSource; | |
| import br.com.softsite.hikarigs.aspect.Tenant; | |
| import br.com.softsite.relatorioservice.relatorio.CompileJasperRecursive; | |
| import br.com.softsite.relatorioservice.relatorio.ReportExporter; | |
| import br.com.softsite.relatorioservice.relatorio.ReportTypes; | |
| import br.com.softsite.relatorioservice.relatorio.WrappedJRException; | |
| import net.sf.jasperreports.engine.JRException; | |
| import net.sf.jasperreports.engine.JRParameter; | |
| import net.sf.jasperreports.engine.JasperFillManager; | |
| import net.sf.jasperreports.engine.JasperPrint; | |
| import net.sf.jasperreports.engine.JasperReport; | |
| import net.sf.jasperreports.engine.fill.JRSwapFileVirtualizer; | |
| import net.sf.jasperreports.engine.util.DeflateStreamCompression; | |
| import net.sf.jasperreports.engine.util.JRSwapFile; | |
| @RestController | |
| public class RelatorioController { | |
| Logger logger = LoggerFactory.getLogger(RelatorioController.class); | |
| @Autowired | |
| TenantRoutingDataSource tenantDataSource; | |
| @Autowired | |
| ConfiguracaoRelatorios config; | |
| @Autowired | |
| CompileJasperRecursive compiler; | |
| @RequestMapping(path = "/{empresa}/{relat}.xlsx", method = RequestMethod.POST, produces = "application/vnd.ms-excel") | |
| @Tenant | |
| public void requisicaoXlsx(@Tenant @PathVariable("empresa") String empresa, | |
| @PathVariable("relat") String relat, | |
| @RequestParam MultiValueMap<String, String> params, | |
| HttpServletRequest req, | |
| HttpServletResponse resp) throws JRException, SQLException, IOException { | |
| compilaRelat(relat, params, ReportTypes.XLSX, () -> { | |
| try { | |
| OutputStream os = resp.getOutputStream(); | |
| resp.setCharacterEncoding("UTF-8"); | |
| resp.setHeader("Content-Disposition", "attachment; filename=" + relat + ".xlsx"); | |
| return os; | |
| } catch (IOException e) { | |
| logger.error("["+empresa.toUpperCase()+"] - " + "["+relat+"] - "+ "[XLS] " + e.getMessage()); | |
| throw new WrappedJRException(e); | |
| } | |
| }); | |
| } | |
| // outros tipos... | |
| private void compilaRelat(String relat, MultiValueMap<String, String> params, ReportTypes reportType, Supplier<OutputStream> outputStream) throws JRException, SQLException, IOException { | |
| JasperReport jasperReport = compiler.getJasperReport(config.getRelatpath() + "/", relat + ".jrxml"); | |
| HashMap<String, Object> map = new HashMap<>(); | |
| params.forEach((k, v) -> { | |
| if (k.endsWith("[]")) { | |
| map.put(k.substring(0, k.length() - 2), v); | |
| } else { | |
| map.put(k, v.get(0)); | |
| } | |
| }); | |
| map.put("P_CAMINHO_SUB_RELAT", config.getRelatpath()); | |
| map.put("REPORT_LOCALE", new Locale("pt", "BR")); | |
| JasperPrint print = fillReport(jasperReport, map); | |
| ReportExporter exporter = new ReportExporter(); | |
| try { | |
| exporter.export(print, outputStream.get(), reportType); | |
| } catch (WrappedJRException e) { | |
| e.throwInner(); | |
| } | |
| } | |
| private JasperPrint fillReport(JasperReport jasperReport, Map<String, Object> params) throws JRException, SQLException { | |
| try (Connection conn = tenantDataSource.getConnection()) { | |
| JRSwapFileVirtualizer virt = new JRSwapFileVirtualizer(512, new JRSwapFile(config.getRelatpath(), 1024, 512), true, new DeflateStreamCompression(1)); | |
| params.put(JRParameter.REPORT_VIRTUALIZER, virt); | |
| return JasperFillManager.fillReport(jasperReport, params, conn); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package br.com.softsite.relatorioservice.relatorio; | |
| import java.io.IOException; | |
| import java.io.OutputStream; | |
| import java.util.Objects; | |
| import java.util.function.BiConsumer; | |
| import net.sf.jasperreports.engine.JRAbstractExporter; | |
| import net.sf.jasperreports.engine.JRException; | |
| import net.sf.jasperreports.engine.JasperPrint; | |
| 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.export.SimpleExporterInput; | |
| import net.sf.jasperreports.export.SimpleHtmlExporterOutput; | |
| import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; | |
| import net.sf.jasperreports.export.SimplePdfExporterConfiguration; | |
| import net.sf.jasperreports.export.SimplePdfReportConfiguration; | |
| import net.sf.jasperreports.export.SimpleWriterExporterOutput; | |
| import net.sf.jasperreports.export.SimpleXlsxReportConfiguration; | |
| public class ReportExporter { | |
| public ReportExporter() { | |
| } | |
| public void exportToPdf(JasperPrint jasperPrint, OutputStream outputStream) { | |
| // print report to file | |
| JRPdfExporter exporter = new JRPdfExporter(); | |
| exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); | |
| exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream)); | |
| SimplePdfReportConfiguration reportConfig = new SimplePdfReportConfiguration(); | |
| reportConfig.setSizePageToContent(true); | |
| reportConfig.setForceLineBreakPolicy(false); | |
| SimplePdfExporterConfiguration exportConfig = new SimplePdfExporterConfiguration(); | |
| exportConfig.setMetadataAuthor("geosales"); | |
| exportConfig.setEncrypted(false); | |
| exportConfig.setAllowedPermissionsHint("PRINTING"); | |
| exporter.setConfiguration(reportConfig); | |
| exporter.setConfiguration(exportConfig); | |
| __export(exporter); | |
| } | |
| public void exportToXlsx(JasperPrint jasperPrint, OutputStream outputStream) { | |
| JRXlsxExporter exporter = new JRXlsxExporter(); | |
| exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); | |
| exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream)); | |
| SimpleXlsxReportConfiguration reportConfig = new SimpleXlsxReportConfiguration(); | |
| reportConfig.setOnePagePerSheet(true); | |
| // reportConfig.setSheetNames(new String[] { sheetName }); | |
| exporter.setConfiguration(reportConfig); | |
| __export(exporter); | |
| } | |
| private void __export(JRAbstractExporter<?, ?, ?, ?> exporter) { | |
| try { | |
| exporter.exportReport(); | |
| } catch (JRException e) { | |
| throw new WrappedJRException(e); | |
| } | |
| } | |
| public void exportToCsv(JasperPrint jasperPrint, OutputStream outputStream) { | |
| JRCsvExporter exporter = new JRCsvExporter(); | |
| exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); | |
| exporter.setExporterOutput(new SimpleWriterExporterOutput(outputStream)); | |
| __export(exporter); | |
| } | |
| public void exportToHtml(JasperPrint jasperPrint, OutputStream outputStream) { | |
| HtmlExporter exporter = new HtmlExporter(); | |
| exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); | |
| exporter.setExporterOutput(new SimpleHtmlExporterOutput(outputStream)); | |
| __export(exporter); | |
| } | |
| public void export(JasperPrint jasperPrint, OutputStream outputStream, ReportTypes type) throws JRException, IOException { | |
| Objects.requireNonNull(type); | |
| BiConsumer<JasperPrint, OutputStream> runner = null; | |
| switch (type) { | |
| case PDF: | |
| runner = this::exportToPdf; | |
| break; | |
| case HTML: | |
| runner = this::exportToHtml; | |
| break; | |
| case CSV: | |
| runner = this::exportToCsv; | |
| break; | |
| case XLSX: | |
| runner = this::exportToXlsx; | |
| break; | |
| } | |
| Objects.requireNonNull(runner); | |
| try { | |
| runner.accept(jasperPrint, outputStream); | |
| } catch (WrappedJRException e) { | |
| e.throwInner(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment