I am using JasperReports for one of my projects to generate PDF reports. However we have this peculiar requirement to be able to print every page of the report into separate PDF files. How to do this in JasperReports programatically?
Thanxs in advance.
Thanxs in advance.
13 Answers:
Posted on August 1, 2007 at 8:43am
Thank you for the solution. I can find the total pages using JasperPrint.getPages().size() and print each page in separate pdf file. However I have a new problem now. I am using one "Report Group" printing the group in a new page always. Now if each record in the report group takes only one page to fill up, then there is no problem, I can print every PAGE_INDEX in separate pdf file. But if any record in the report group take more than one page to fill, then printing each PAGE_INDEX in separate file won't be correct as a single record in the report group will take multiple files while printing. So I need to know the start and end PAGE_INDEX of every record in the report group so that I can print every record in the report group to its own pdf file. How can I do that?
Thank you for spending time for me.
Thank you for spending time for me.
Posted on August 6, 2007 at 10:16am
Ok, that will be a bit tricky solution. Now I am thinking if this can be achieved from report query by some filetering as follows:
1) Assuming a parameter SUB_GROUP_ID, if it's value is null (or -1), then don't filter result by SUB_GROUP_ID.
2) If value of SUB_GROUP_ID is not null or > 0, then filter the result by SUB_GROUP_ID so that only report for that SUB_GROUP_ID will be generated whatever no of pages it might take.
The solution seems perfect for my case. But I am unable to achieve this. I can't give a calculated string value in report query. Is there any other workaround to apply such filter dynamically ( not programatically)?
1) Assuming a parameter SUB_GROUP_ID, if it's value is null (or -1), then don't filter result by SUB_GROUP_ID.
2) If value of SUB_GROUP_ID is not null or > 0, then filter the result by SUB_GROUP_ID so that only report for that SUB_GROUP_ID will be generated whatever no of pages it might take.
The solution seems perfect for my case. But I am unable to achieve this. I can't give a calculated string value in report query. Is there any other workaround to apply such filter dynamically ( not programatically)?
Posted on August 6, 2007 at 11:58am
I don't understand what are you trying to achieve with the query filter, but you can implement such a filter in the following way:
Code: |
<br /> <parameter name="SUB_GROUP_ID" class="java.lang.Integer"/><br /> <parameter name="SUB_GROUP_FILTER" isForPrompting="false"><br /> <defaultValueExpression><![CDATA[<br /> ($P{SUB_GROUP_ID} == null || $P{SUB_GROUP_ID}.intValue() < 0) ?<br /> "" :<br /> " AND SubGroupCol = $$P{SUB_GROUP_ID}"<br /> ]]></defaultValueExpression><br /> </parameter><br /> <queryString><![CDATA[<br /> SELECT ... WHERE ... $P!{SUB_GROUP_FILTER}<br /> ]]></queryString><br /> </td></tr></tbody></table><br /> <br /> Note that <i>" AND SubGroupCol = $$P{SUB_GROUP_ID}"</i> would only work in JR >= 1.3.2, if have an older version you will have to use <i>" AND SubGroupCol = " + $P{SUB_GROUP_ID}</i>.<br /> <br /> HTH,<br /> Lucian |
Posted on August 10, 2007 at 7:11am
Thank you. The parameter solution did worked.
Now having two solutions for the problem, I start to wonder which one is better(performance, speed)?
Since filling is done only once by Jasper engine in the first solution (putting a hidden field), I guess this one may be faster but I don't know how much time consuming will the searching the hidden field will be?
But in second case, filling will be done multiple times not for all records, but only for those filtered by SUB_GROUP.
Hoping to get guidance once again.
Now having two solutions for the problem, I start to wonder which one is better(performance, speed)?
Since filling is done only once by Jasper engine in the first solution (putting a hidden field), I guess this one may be faster but I don't know how much time consuming will the searching the hidden field will be?
But in second case, filling will be done multiple times not for all records, but only for those filtered by SUB_GROUP.
Hoping to get guidance once again.
Posted on August 10, 2007 at 9:51am
My guess is that filling a single report would be faster. Searching for a field in a JasperPrint page only involves going through the element list and testing the element key against a String, so I wouldn't worry about that.
This is only my guess, if you want an actual comparison you should implement both solution and do some performance tests.
Regards,
Lucian
This is only my guess, if you want an actual comparison you should implement both solution and do some performance tests.
Regards,
Lucian
Posted on August 15, 2007 at 12:34pm
Thank you for the useful thought. I have implemented both solutions and tried running both for a simple report containing 3 sub groups. From my simple experiment, method with finding control in jasper file seems a little bit faster than the query filtering method. However a report may actually contain more than 100 sub groups. The main point for comparison here is which process is faster: searching for control in jasper file in 100+ pages (each sub group can span multiple pages) or filling 100+ sub reports using query filtering. I think the first one will be faster.
Thank you once again for your timely response.
Thank you once again for your timely response.
Posted on August 16, 2007 at 8:46am
I ran into the problem once again. When implementing the hidden element solution, I put one text field holding SUB_GROUP_ID in the report group header. When this field is printed in the file (currently pdf), then the java code can find the control and can read it text property. However when I hide the field ( by setting new Boolean(false) in the print when expression, then the java code can't find the element as it seems that the method
JRPrintPage.getElements()
returns only printed elements. Then I changed the element width and height to 5px. Now the java code can find the control, but getText() returns empty string. The interesting point here is while debugging in eclipse shows the field "value" of String holding array of characters of actual value of the field, the String itself is empty with count, hash, offset all set to zero.
Then I increased the width and height of the field to only show the 1st character of it's value. Now the getText() returns only the 1st character that is printed. When I increased both height and width to show the full value, then only the getText() returned the full value. So it seems like the element holds only the printed character. But I don't want to print the value in the report.
Now, how can I read the correct value from the element ? And can we read value from hidden (not printed) elements?
JRPrintPage.getElements()
returns only printed elements. Then I changed the element width and height to 5px. Now the java code can find the control, but getText() returns empty string. The interesting point here is while debugging in eclipse shows the field "value" of String holding array of characters of actual value of the field, the String itself is empty with count, hash, offset all set to zero.
Then I increased the width and height of the field to only show the 1st character of it's value. Now the getText() returns only the 1st character that is printed. When I increased both height and width to show the full value, then only the getText() returned the full value. So it seems like the element holds only the printed character. But I don't want to print the value in the report.
Now, how can I read the correct value from the element ? And can we read value from hidden (not printed) elements?
Posted on August 20, 2007 at 1:46pm
If an element's print when expression evaluates to false, the element does not produce a print element in the resulting document.
My advice was to use the element key (as in <reportElement key=".."> and JRPrintElement.getKey()) to identify the element. You won't have to worry about the element text this way. Note that this requires JR >= 1.2.8.
Regards,
Lucian
My advice was to use the element key (as in <reportElement key=".."> and JRPrintElement.getKey()) to identify the element. You won't have to worry about the element text this way. Note that this requires JR >= 1.2.8.
Regards,
Lucian