Search code examples
jasper-reports

Changing jasper report parameters in runtime


I know, but we really need it. We have a clear division of labor. They create templates, I fill them in runtime according to some rules.

  • Can't teach my business to insert something like this and be sure they really did it ok(so can't move any logic to templates):

$P{risk_types}.get($F{risk_type}) ?: "UNDEFINED"

  • Also can not fill from files hardcoded in some adapter hadwritten by god-knows-who and unchangeable in runtime. It's a web app. Best option is to find a way to replace that file source from adapter to a ByteArrayStream.

SO: Need to substitute contents of parameters(also default ones) at runtime. example: need to set JSON_INPUT_STREAM

Like this unsolved thread. https://community.jaspersoft.com/questions/516611/changing-parameter-scriptlet Really hope not to work on xml level, but xml also can't solve my problem as far as I tried. Thank you!


Solution

  • The easiest and cleanest way we did this(bypassing usage of tons of deprecated documentation and unfinished bugged undocumented static antipatterned new features):

    Create context with repository extension

    SimpleJasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
    jasperReportsContext.setExtensions(RepositoryService.class, Collections.singletonList(new MyRepositoryService(jasperReportsContext, yourOptionalParams)));
    

    Fill this way(after compile and other usual actions)

    JasperPrint print = JasperFillManager.getInstance(jasperReportsContext).fill(compiled, new HashMap<>());
    

    Now your repository must extend default one to be hack-injected(cause of hodgie coded "isAssignableFrom") successfully

    public class PrintFormsRepositoryService extends DefaultRepositoryService {
    
        @Override
        public InputStream getInputStream(RepositoryContext context, String uri) {
            // return here your own good simple poj inputStream even from memory if you found source
            // or pass to another repository service(default one probably)
            return null;
        }
    
    }