Last active
November 15, 2024 09:35
-
-
Save rponte/3784718 to your computer and use it in GitHub Desktop.
Automatic compilation of subreports with JasperReports
This file contains 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.triadworks.controller.relatorios.jasper; | |
import java.io.ByteArrayOutputStream; | |
import java.sql.Connection; | |
import java.util.Map; | |
import javax.sql.DataSource; | |
import net.sf.jasperreports.engine.JRException; | |
import net.sf.jasperreports.engine.JRExporter; | |
import net.sf.jasperreports.engine.JRExporterParameter; | |
import net.sf.jasperreports.engine.JasperCompileManager; | |
import net.sf.jasperreports.engine.JasperFillManager; | |
import net.sf.jasperreports.engine.JasperPrint; | |
import net.sf.jasperreports.engine.JasperReport; | |
import net.sf.jasperreports.engine.export.JRPdfExporter; | |
import net.sf.jasperreports.engine.util.JRElementsVisitor; | |
import org.springframework.jdbc.datasource.DataSourceUtils; | |
import br.com.syspdv.exceptions.RelatorioNaoGeradoException; | |
public class JasperReportBuilder { | |
private final DataSource dataSource; | |
public JasperReportBuilder(DataSource dataSource) { | |
this.dataSource = dataSource; | |
} | |
public byte[] build(String jrxmlFile, Map<String, Object> parameters) { | |
try { | |
JasperPrint print = compileAndFillReport(jrxmlFile, parameters); | |
byte[] content = exportToPdf(print); | |
return content; | |
} catch (Exception e) { | |
throw new RelatorioNaoGeradoException(e.getMessage(), e); | |
} | |
} | |
private JasperPrint compileAndFillReport(String jrxmlFile, Map<String, Object> parametros) throws JRException { | |
JasperReport report = JasperCompileManager.compileReport(jrxmlFile); | |
JRElementsVisitor.visitReport(report, new SubReportVisitor("/repositorio/de/jaspers/")); // the magic is here! | |
JasperPrint print = fillReport(parametros, report); | |
return print; | |
} | |
private byte[] exportToPdf(JasperPrint print) throws JRException { | |
JRExporter exporter = new JRPdfExporter(); | |
ByteArrayOutputStream exported = new ByteArrayOutputStream(); | |
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, exported); | |
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); | |
exporter.exportReport(); | |
return exported.toByteArray(); | |
} | |
private JasperPrint fillReport(Map<String, Object> parametros, JasperReport report) throws JRException { | |
Connection connection = null; | |
try { | |
connection = getConnection(); | |
return JasperFillManager.fillReport(report, parametros, connection); | |
} finally { | |
DataSourceUtils.releaseConnection(connection, dataSource); | |
} | |
} | |
private Connection getConnection() { | |
try { | |
return DataSourceUtils.getConnection(dataSource); | |
} catch (Exception e) { | |
throw new IllegalStateException("Impossivel obter uma conexão com o banco de dados.", e); | |
} | |
} | |
} |
This file contains 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.triadworks.controller.relatorios.jasper; | |
import java.io.File; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import net.sf.jasperreports.engine.JRSubreport; | |
public class SubReportInfo { | |
private final static Pattern FILENAME_PATTERN = Pattern.compile("\"(.*?.jasper)"); | |
private final File sourceSubreport; | |
private final File compiledSubreport; | |
public SubReportInfo(JRSubreport subreport, String jasperPath) { | |
String filename = extractFilename(subreport); | |
this.compiledSubreport = new File(jasperPath, filename); | |
this.sourceSubreport = new File(jasperPath, filename.replaceAll(".jasper", ".jrxml")); | |
} | |
public String getJRXMLFilename() { | |
return sourceSubreport.getName(); | |
} | |
public String getJRXMLFilepath() { | |
return sourceSubreport.getAbsolutePath(); | |
} | |
public boolean shouldCompile() { | |
if (!compiledSubreport.exists()) return true; | |
return (compiledSubreport.lastModified() < sourceSubreport.lastModified()); | |
} | |
public String extractFilename(JRSubreport subreport) { | |
String expression = subreport.getExpression().getText(); | |
Matcher matcher = FILENAME_PATTERN.matcher(expression); | |
if (matcher.find()) { | |
if (matcher.groupCount() > 0) { | |
return matcher.group(1); | |
} | |
} | |
throw new IllegalStateException("Não foi possível obter o nome do subrelatório da expressão '" + expression +"'." ); | |
} | |
} |
This file contains 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.triadworks.controller.relatorios.jasper; | |
import net.sf.jasperreports.engine.JRException; | |
import net.sf.jasperreports.engine.JRSubreport; | |
import net.sf.jasperreports.engine.JasperCompileManager; | |
import net.sf.jasperreports.engine.util.JRVisitorSupport; | |
public class SubReportVisitor extends JRVisitorSupport { | |
private final String jasperPath; | |
public SubReportVisitor(String jasperPath) { | |
this.jasperPath = jasperPath; | |
} | |
@Override | |
public void visitSubreport(JRSubreport subreport) { | |
SubReportInfo subReportInfo = new SubReportInfo(subreport, jasperPath); | |
compile(subReportInfo); | |
} | |
private void compile(SubReportInfo subReportInfo) { | |
try { | |
if (subReportInfo.shouldCompile()) | |
JasperCompileManager.compileReportToFile(subReportInfo.getJRXMLFilepath()); | |
} catch (JRException e) { | |
throw new IllegalStateException("Não foi possível compilar o subrelatório '" + subReportInfo.getJRXMLFilename() + "'.", e); | |
} | |
} | |
} |
This file contains 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
public class TestingJasperReportBuilder { | |
public static void main(String[] args) { | |
DataSource dataSource = DataSourceFactory.default(); // your datasource | |
Map<String, Object> parameters = new HashMap<String, Object>(); | |
JasperReportBuilder builder = new JasperReportBuilder(dataSource); | |
byte[] bytes = builder.build("report.jrxml", parameters); | |
} | |
} |
Eu tenho um relatorio com 2 niveis de sub, isso funcionaria? Report tem um sub e o sub tem outro sub.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
More informations,
http://stackoverflow.com/questions/10004800/jasper-reports-how-to-compile-subreports
http://issues.opennms.org/browse/NMS-4552?attachmentSortBy=dateTime