Home » Archived » BIRT » RunTask+RenderTask vs. RunAndRenderTask(Using the same render options, the two strategies lead to different results, I don't understand why)
RunTask+RenderTask vs. RunAndRenderTask [message #1114922] |
Mon, 23 September 2013 08:11  |
Eclipse User |
|
|
|
Hi,
I use two different strategies to create BIRT reports due to performance reasons and assumed that the result should be the same, but it turns out it isn't.
Context: User's of my application can configure whether they want to export data in either PDF or HTML or in both formats at once.
In case that both formats should be exported, I create a RunTask instance once (to store the runtime report design) and then use a RenderTask instance to render both outputs.
For the case of only one output (PDF or HTML), I wanted to make use of the RunAndRenderTask class since it seems to be a bit more perfomant in terms of memory consumption than my former approach.
Since I encountered a page overflow issue lately which I describe here, I had to set the PAGE_OVERFLOW option to FIT_TO_PAGE_SIZE for PDF rendering to avoid doubled pages. As a consequence of that, it turned out that my two strategies now produce differently layouted results and I cannot figure out why (since I set up the same engine options as well as render options).
Here is how the two strategies are basically implemented (I rewrote it in two separate functions for this post, to make it better comparable):
Version 1: runTask + renderTask
private List<String> generateBirtReportV1(Resource transformedResource, final IProgressMonitor subMonitor)
throws EngineException {
subMonitor.beginTask("Generate Birt report", 31);
EngineConfig config = createEngineConfig();
IReportEngine engine = createEngine(config);
final List<String> filesToOpen = Lists.newArrayList();
try {
checkAndHandleMonitorCanceled();
IReportRunnable reportRunnable = null;
for (final Format f : this.formats) {
final IFile file = getOutputFile(f);
// we only have to run this task once for all output formats
if (reportRunnable == null) {
reportRunnable = runRunTask(engine, transformedResource, subMonitor);
}
runRenderTask(engine, reportRunnable, f, transformedResource, subMonitor);
final IFile file = getOutputFile(f);
String path = file.getLocation().toPortableString();
filesToOpen.add(path);
}
} finally {
engine.destroy();
subMonitor.done();
}
return filesToOpen;
}
protected IReportRunnable runRunTask(IReportEngine engine, Resource transformedResource, final IProgressMonitor monitor) throws EngineException {
IReportRunnable design = getReport(engine);
if (design == null) {
return null;
}
final IRunTask runTask = engine.createRunTask(design);
setCommonTaskSettings(runTask, transformedResource);
try {
runTask.run(getTargetPath().concat(".rptdocument"));
return runTask.getReportRunnable();
} finally {
runTask.close();
}
}
protected void runRenderTask(IReportEngine engine, IReportRunnable reportRunnable, Format format,
Resource transformedResource, final IProgressMonitor monitor) throws EngineException {
IReportDocument reportDocument = engine.openReportDocument(getTargetPath().concat(".rptdocument"));
final IRenderTask renderTask = engine.createRenderTask(reportDocument, reportRunnable);
renderTask.setRenderOption(createRenderOption(format));
setCommonTaskSettings(renderTask, transformedResource);
try {
renderTask.render();
} finally {
renderTask.close();
reportDocument.close();
disposeOutputStream();
}
}
Version2: RunAndRenderTask (which is used for all formats in this example)
private List<String> generateBirtReportV2(Resource transformedResource, final IProgressMonitor subMonitor)
throws EngineException {
subMonitor.beginTask("Generate Birt report", 31);
EngineConfig config = createEngineConfig();
IReportEngine engine = createEngine(config);
final List<String> filesToOpen = Lists.newArrayList();
try {
checkAndHandleMonitorCanceled();
for (final Format f : this.formats) {
runRunAndRenderTask(engine, f, transformedResource, new SubProgressMonitor(subMonitor, 20));
final IFile file = getOutputFile(f);
String path = file.getLocation().toPortableString();
filesToOpen.add(path);
}
} finally {
engine.destroy();
subMonitor.done();
}
return filesToOpen;
}
protected void runRunAndRenderTask(IReportEngine engine, Format format, Resource transformedResource, final IProgressMonitor monitor) throws EngineException {
IReportRunnable design = getReport(engine);
if (design == null) {
return;
}
final IRunAndRenderTask runAndRenderTask = engine.createRunAndRenderTask(design);
runAndRenderTask.setRenderOption(createRenderOption(format));
setCommonTaskSettings(runAndRenderTask, transformedResource);
try {
runAndRenderTask.run();
} catch (OperationCanceledException e) {
if (monitor.isCanceled()) {
return;
}
throw e;
} finally {
runAndRenderTask.close();
disposeOutputStream();
monitor.done();
}
}
As you can see, I use the same methods to create the render options and to set common task settings, which look like this:
protected void setCommonTaskSettings(IEngineTask engineTask, Resource transformedResource) {
// ** locale
engineTask.setLocale(new Locale(this.language));
// ** Parameter Values
if (transformedResource != null) {
engineTask.setParameterValue("resource", transformedResource.getURI().toString());
}
engineTask.setParameterValue("project", toPlatformURIString(this.project).concat("/"));
engineTask.setParameterValue("title", this.title);
engineTask.setParameterValue("isTrial", ReportPlugin.getInstance().isTrial());
// set parameter logo if user specified custom logo
SpecConfigModel specConfigModel = getReportModel();
String logoFilePath = specConfigModel.getLogoFilePath();
if (logoFilePath != null && logoFilePath.length() > 0) {
IPath path = new Path(logoFilePath);
engineTask.setParameterValue("logo", "reports/customlogo/" + path.lastSegment());
} // otherwise do nothing, the parameter logo should have a sensible
// default in the rptdesign file
String footer = specConfigModel.getFooter();
if (footer != null && !Activator.isTrial()) {
engineTask.setParameterValue("footer", footer);
} // otherwise do nothing, there is a default footer
}
protected IRenderOption createRenderOption(final Format format1) {
switch (format1) {
case HTML:
HTMLRenderOption htmlRenderOption = new HTMLRenderOption();
htmlRenderOption.setOutputFileName(getOutputFileName(format1));
htmlRenderOption.setOutputFormat(getBIRTFormat(format1));
htmlRenderOption.setImageDirectory("images");
htmlRenderOption.setHtmlTitle(this.title);
htmlRenderOption.setEnableAgentStyleEngine(true);
htmlRenderOption.setEnableInlineStyle(false);
htmlRenderOption.setEnableCompactMode(true);
return htmlRenderOption;
case PDF:
default:
PDFRenderOption pdfRenderOption = new PDFRenderOption();
pdfRenderOption.setOption(IPDFRenderOption.DPI, 96);
OutputStream outputStream = createOutputStream(format1);
if (outputStream != null) {
pdfRenderOption.setOutputStream(outputStream);
} else {
pdfRenderOption.setOutputFileName(getOutputFileName(format1));
}
pdfRenderOption.setOutputFormat(getBIRTFormat(format1));
pdfRenderOption.setOption(IPDFRenderOption.PDF_HYPHENATION, Boolean.TRUE);
pdfRenderOption.setOption(IPDFRenderOption.PDF_TEXT_WRAPPING, Boolean.TRUE);
pdfRenderOption.setOption(IPDFRenderOption.PAGE_OVERFLOW, IPDFRenderOption.FIT_TO_PAGE_SIZE);
return pdfRenderOption;
}
}
For Version 1, the layout for the PDF is as expected. BIRT adds page breaks automatically where appropriate, and in case of the issue I described in the other post, the page is shrunk a little to avoid doubled pages. However, the second version shrinks all contents between two explicitly added page breaks (in my rptdesign file, I have some occasions where I ALWAYS set a page break before a new heading), i.e. BIRT is not adding smart page breaks automatically.
I tried to debug the different EngineTasks but wasn't able to figure out where the different layout behavior comes from.
Any ideas?
|
|
| | | | | |
Goto Forum:
Current Time: Wed Mar 26 08:13:06 EDT 2025
Powered by FUDForum. Page generated in 0.03253 seconds
|