Skip to content

Instantly share code, notes, and snippets.

@jeffque
Last active December 31, 2021 02:50
Show Gist options
  • Select an option

  • Save jeffque/6fe3386982b00fe7ed5a3d2ac499bf0d to your computer and use it in GitHub Desktop.

Select an option

Save jeffque/6fe3386982b00fe7ed5a3d2ac499bf0d to your computer and use it in GitHub Desktop.
Compilação recursiva jasper
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");
}
}
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");
}
}
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);
}
}
}
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