Jump to content
Changes to the Jaspersoft community edition download ×

Right to left arabic Reports


sukirtha

Recommended Posts

I want the report to become Right To Left(RTL) when the user chooses language as Arabic. If the report is exported as PDF, Word, or Excel in Arabic, the report should be displayed in RTL. Is this possible using jasper reports? Please help...

Link to comment
Share on other sites

  • Replies 24
  • Created
  • Last Reply

Top Posters In This Topic

First of all thank you Lucian for your reply.

 

I achieved RTL for html reports by embedding the reports inside a normall jsp page and setting dir="rtl" in the <body> tag. I still have to check the correctness of the report though. :)

 

The problem is for RTF, Excel and PDF formats. I am not planning to allow PDF export, so I need not worry about that currently. If we set the character encoding for the report as UTF-8, use unicode character for arabic letters and if we opened the report using excel with regional settings as Arabic, I wonder if excel will handle the RTL conversion by itself... If anyone has any experience with using Excel & Word regional settings, please share it here.

 

Thanks for all the help.

Link to comment
Share on other sites

I tried installing arabic support for Microsoft office and I set UTF-8 to be my encoding however, the RTL will not get invoked for me. I need to somehow achieve the functionality. So looks like I may have to make changes to the Export code.

 

I also came to know that Crosstab reports generated through jasper supports RTL. Can the same be applied to other types of reports as well? Sorry if I am being silly. If no, then can someone point me to the right direction from where I can start making the changes?

 

Thanks

Link to comment
Share on other sites

sukirtha wrote:

I tried installing arabic support for Microsoft office and I set UTF-8 to be my encoding however, the RTL will not get invoked for me.

 

Could you clarify what "the RTL will not get invoked" means? What format are you exporting to? Are the Arabic texts displayed correctly?

 

I also came to know that Crosstab reports generated through jasper supports RTL. Can the same be applied to other types of reports as well?

 

As I said before, the overall report layout cannot be changed/mirrored to achieve automatic LTR/RTL output. The crosstab RTL feature is specific to crosstabs.

 

If no, then can someone point me to the right direction from where I can start making the changes?

 

What you could try is to use the JasperReports API to alter the layout of a JasperPrint object by mirroring the position of all generated print elements. Alternatively, you can use the API to mirror the layout of a JasperDesign object, so that the report would be directly generated in RTL layout.

 

Regards,

Lucian

Link to comment
Share on other sites

Could you clarify what "the RTL will not get invoked" means? What format are you exporting to? Are the Arabic texts displayed correctly?

 

I have created a report that may contain arabic data as well as english data. In my application, the user gets to choose the language preference. If the user chooses language option as arabic, The entire set of screens as well as any other report generated should be have RTL direction. This said, I have created a report, a simple report which has static and dynamic text contents. I set encoding as UTF-8. I also set report locale as Arabic(Kuwait). As expected, the report is not mirrored. As you said, jasper doesn't handle RTL which is in a way correct. I was hoping that Excel will handle RTL based on the default setting. I have set RTL as the default direction in Excel. Despite the default settings, My report gets displayed in LTR.

 

Having said that I have three options left at hand:

1) Change the jasper excel and RTF export codes. I am not sure how much time and effort it will take to complete this approach

 

2) Invoke a macro to enable RTL in excel and word. I still have to figure out when and where the invokation should happen. The problem with this approach is that the user could have disabled macros. Time factor is another problem here.

 

3) Another simple workaround is to generate the reports in html and save them with .xls and .rtf extensions. As I have accomplished mirooring of html reports, I think this can get me the report in both Excel and RTF formats. The downside of this approach is that the report will not be very neat and formatted and I end up losing functionalities specific to excel.

 

I am not sure which of the three approaches to take. Can you please suggest the best approach. I have minimal time in hand. Thanks in advance for your help

Link to comment
Share on other sites

I'm not familiar with the RTL support in Excel/RTF, so I might not be able to suggest you the best solution.

One thing that you might want to try is my suggestion from the previous message. After you fill a report to a JasperPrint object, you can programmatically mirror the layout of the generated report by using a helper class like:

Code:

Note that by this you only change the position of the elements, other attributes such as borders are not mirrored.

I'm not sure whether this would yield the expected result, especially for Excel. Give it a try and see whether the output is what you expect.

 

Regards,
Lucian

Link to comment
Share on other sites

Hi Lucian,
First of all, thank you for sharing the code for mirroring. It has solved half my problem. I am sure I can use this code to build the other features I require.

I have few doubts however...

1) My reports are going to be huge. Millions of records at a time. This mirroring may cause performance problem as we are trying to mirror every element present in the Print object. As far as I understand, a print object contains the data as well as the report design. So if there are 1000 records in my database, and i am displaying 4 columns per record, then I am going to have 1000 * 4 = 4000 elements in the print object and each element has to undergo this mirroring process. To avoid this, can we mirror the design instead of the print object. Correct me if I am wrong, the design just contains the layout and there no data. So mirroring that would take lesser time I suppose. I could be completely wrong. Please correct me if I am wrong.


2) How about the alignment of the text within a text element? Should that be handled during mirroring? If yes how can I go about doing that?

Thanks in advance for your reply. [file name=RTF.zip size=22354]

Link to comment
Share on other sites

sukirtha wrote:


1) My reports are going to be huge.
...
To avoid this, can we mirror the design instead of the print object. Correct me if I am wrong, the design just contains the layout and there no data. So mirroring that would take lesser time I suppose.


You are correct. If you are going to generate large reports, mirroring the elements in the report design would be faster.
 

2) How about the alignment of the text within a text element? Should that be handled during mirroring? If yes how can I go about doing that?


I think the best thing is that you decide yourself whether mirroring the text alignment is required. Create a report with left and right aligned text elements, and see whether the Arabic output is as you'd expect it.

If you need to mirror the alignment, you'd only have to do something like (I'm assuming that you are mirroring the report design):

Code:


Regards,
Lucian

Link to comment
Share on other sites

Thank you Lucian for the sharing the snippet. It is really useful. I have decided to mirror the jasperDesign object instead of the print object for performance reasons. Also, because compilation happens only after loading the design, we opted to mirror the design and then compile so that we could even choose to do the mirroring and compilation offline.

 

Now, incase we decide to do compilation ONLINE I have the following doubts.

 

1) How can I mirror the subreports and groups inside a main report? Should I treat the subreports as seperate reports and mirror the design of the subreports independant of the main report?

 

2) The second doubt has nothing to do with arabic RTL but still I came up with this doubt while working with RTL so thought might as well ask it here.

If I load the the mirrored design of the main report and compile it online and store the jasperReport object in memory (NOT as .jasper file in the server) and if I have sub reports under the main report, how can I compile the subreports and store them as JasperReports object in the memory (NOT as .jasper file) such that the main report can access the subreport? Or in simple terms, I don't want to create .jasper files. Instead I want to create JasperReport objects. I also want to maintain the relationship between the Main and Subreport JasperReport objects. Is it possible??

 

Thank you for your time and suggestion.

Link to comment
Share on other sites

sukirtha wrote:


1) How can I mirror the subreports and groups inside a main report? Should I treat the subreports as seperate reports and mirror the design of the subreports independant of the main report?


Yes, subreports should be mirrored as independent reports.
 

2) The second doubt has nothing to do with arabic RTL but still I came up with this doubt while working with RTL so thought might as well ask it here.
If I load the the mirrored design of the main report and compile it online and store the jasperReport object in memory (NOT as .jasper file in the server) and if I have sub reports under the main report, how can I compile the subreports and store them as JasperReports object in the memory (NOT as .jasper file) such that the main report can access the subreport? Or in simple terms, I don't want to create .jasper files. Instead I want to create JasperReport objects. I also want to maintain the relationship between the Main and Subreport JasperReport objects. Is it possible??


Deploying in-memory subreports is possible, all you have to do is to write a subreport expression that produces JasperReport instances. For instance, if you have a repository-like service for JasperReport instances, you could pass it as a parameter to the master report and use it to resolve subreport objects:

Code:


I didn't understand the question about the relationship between main reports and subreports. What exactly do you want to do?

Regards,
Lucian

Link to comment
Share on other sites

For instance, if you have a repository-like service for JasperReport instances, you could pass it as a parameter to the master report and use it to resolve subreport objects

 

I am not sure what you mean by a report repository service. Is it a class that just returns an instance of the JasperReport being requested? A central manager that creates report instances?

 

I didn't understand the question about the relationship between main reports and subreports. What exactly do you want to do?

 

By relationship I meant that the main report by itself instantiates an instance of the subreport present in it so that the main report has a reference to the subreport that it contains. I don't know if what I am asking really makes sense. I guess your solution will solve my problem if you could please clarify on the report repository concept

Link to comment
Share on other sites

sukirtha wrote:

I am not sure what you mean by a report repository service. Is it a class that just returns an instance of the JasperReport being requested? A central manager that creates report instances?

 

Yes, a report repository service would be a manager that returns in-memory JasperReports instances based on some report keys/IDs. You need to implement something like that yourself because when you don't have physical *.jasper files/resources/locations (that JR is able to load on its own), JR doesn't know how to retrieve in-memory JasperReport instances.

 

Regards,

Lucian

Link to comment
Share on other sites

So at any point in time there will be just one JasperReport instance per report. Am I right? DO you have any sample for report repository service? If yes, can you please share them here? If No, I would still like to thank you for all the help this far. I am now aware of what needs to be done to achieve most of the report specific requirements for my project. Once again a big THANK YOU! :)
Link to comment
Share on other sites

sukirtha wrote:

So at any point in time there will be just one JasperReport instance per report. Am I right?

 

Well, that's up to you, a subreport just needs to use a JasperReport instance. In most cases caching and sharing such instances is a good idea because report compilation takes some time and (if it's possible) it's better only to compile a report the first time you use it. However, if this doesn't make sens in your application, you can return fresh JasperReport instance at each call.

 

DO you have any sample for report repository service?

 

I'm afraid I don't. Such a service would be specific to your application, as its implementation would depend on the application's architecture and flow (e.g. where you get the .jrxml files from, what kind of processing you perform on them, how caching would work and so on).

 

Regards,

Lucian

Link to comment
Share on other sites

No problem. I will try to implement a repository that suits my application. One last question. I mirrored the design object and I exported the report in RTF format. However the report's right margin gets cut automatically. Here is the code. DO you see any issues here. I reused the code snippet you gave. Your code works well for mirroring print object. Am I missing something for the design mirroring?
 

Code:

Please see the attached report rtf [file name=Report-ea7f551ac1e2c08afdb810859b926bf9.zip size=120353]

Link to comment
Share on other sites

Hi Lucian,
This is in continuation to the in-memory subreports access.
 


 

I have used the quoted approach to accomodate in memory subreports.

I have created a very basic report repository class. The class merely generates a JasperReport object for the requested report name.

I tried generating a main report with two subreports directly under it. There are no exceptions thrown while running the report. The database has data but no report is generated. Only an empty file gets exported. I think there could be problem with the JasperReport to JasperPrint conversion.

Here is the code in my ReportExporter Class:

Code:


Here is the ReportRepository class:
 

Code:


JRXML of the Main Report :
 

Code:


What am I missing here. Thanks in advance for your help.

Regards
Sukirtha Joseph
Post edited by: sukirtha, at: 2008/07/10 04:39

Link to comment
Share on other sites

I also tried debugging. The value inside the JasperReport instance of the main report has a reference to the subreport inside the title band Whereas the JasperPrint has 0 pages within it. Could this be a layout problem. For your information, the Title band of the main report includes a sub-report which has nothing but static texts. This title should contain the report cover page details, which would be common for all the reports.

 

So the layout will have the following structure.

 

ReportHeader (pageHeader band of the main report)

ReportCoverPage (A Subreport - placed in the title band of the main report)

ReportData (A Subreport - Place in the Details band of the main report)

FooterDetails (pageFooter band of the main report)

 

 

Do you see any issues with layout itself?

Link to comment
Share on other sites

sukirtha wrote:


What am I missing here.


 

As far as I can tell, you're missing several things:


HTH,
Lucian

Link to comment
Share on other sites

I made the changes you asked me to do and I am getting only the page header band in the report.
 

The master report has no query and you're not sending any explicit data source either, so it won't have any data to iterate on. And since you have whenNoDataType="NoPages", an empty report will be produced.


So does that mean my main report should definitely contain some datasource to provide an output. In my scenario, my main report is just a static template over which I place all the subreports. I am providing a query in the subreport jrxls. I did not post my subreport in my previos post so here it is:
 

Code:


Is the query in the subreport not enough to render the report???
 

The master report has no query and you're not sending any explicit data source either


If I don't specify a query in the jrxml, can I specify it during runtime. That is, can my java code pass a query to jasper during runtime based on which the report will be filled. If yes can you let me know how?

Passing database query at runtime to report

I have posted the same question in the above URL.
Thanks for your reply.

Link to comment
Share on other sites

sukirtha wrote:

In my scenario, my main report is just a static template over which I place all the subreports.

 

Then don't use the detail band, or send new JREmptyDataSource() when filling the report. The detail band is only rendered when the report data source contains records.

 

HTH,

Lucian

Link to comment
Share on other sites

  • 4 years later...
  • 1 year later...

1.Create a Class as follows:-

public class ReportUtils
{
    public static void mirrorLayout(JasperPrint print)
    {
    int pageWidth = print.getPageWidth();
    for (Iterator it = print.getPages().iterator(); it.hasNext();)
    {
        JRPrintPage page = (JRPrintPage) it.next();
        mirrorLayout(page.getElements(), pageWidth);
    }
    }
 
    protected static void mirrorLayout(List elements, int totalWidth)
    {
    for (Iterator it = elements.iterator(); it.hasNext();)
    {
        JRPrintElement element = (JRPrintElement) it.next();
        int mirrorX = totalWidth - element.getX() - element.getWidth();
        element.setX(mirrorX);
 
        if (element instanceof JRPrintFrame)
        {
        JRPrintFrame frame = (JRPrintFrame) element;
        mirrorLayout(frame.getElements(), frame.getWidth());
        }
    }
    }
}

2. Call this method from your present Class,  like follows

try {
            Connection con = JavaConnection.GetCon();
            JasperDesign jd = JRXmlLoader.load("report1.jrxml"); // your report path and name
            JasperReport jr = JasperCompileManager.compileReport(jd);
            JasperPrint jp = JasperFillManager.fillReport(jr, null, con);
            ReportUtils.mirrorLayout(print); //for Arabic print right to left mirror
            JasperPrintManager.printReport(jp,false);// it will send print directly to printer
        } catch (JRException e) {
            JOptionPane.showMessageDialog(null, e);
        }

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...