#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2005
    Posts
    1
    Rep Power
    0

    Relative Path for subreport in JasperReport


    I am using jasperReport with iReport. I want to give the relative path of subreport (VendorWiseSubReport.jasper)but i am unable to do it.
    Please help me.
    Thanks in advance

    <parameter name="ReportSubReport" isForPrompting="false" class="java.lang.String">
    <defaultValueExpression ><![CDATA["C:\\Reports\\StrutsProj\\WebContent\\reports\\VendorWisePartSubReportBP.jasper"]]></defaultValueExpression>
    </parameter>
    Last edited by rajeevshishodia; December 3rd, 2005 at 02:36 AM. Reason: Something was missing
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    4
    Rep Power
    0

    Arrow


    Originally Posted by rajeevshishodia
    I am using jasperReport with iReport. I want to give the relative path of subreport (VendorWiseSubReport.jasper)but i am unable to do it.
    Please help me.
    Thanks in advance

    <parameter name="ReportSubReport" isForPrompting="false" class="java.lang.String">
    <defaultValueExpression ><![CDATA["C:\\Reports\\StrutsProj\\WebContent\\reports\\VendorWisePartSubReportBP.jasper"]]></defaultValueExpression>
    </parameter>

    I agree with everyone complaining about this issue with relative paths (for images, subreports, etc.)
    Actually JasperReports offers MANY ways to use it, but unfortunately it's very undocumented.
    I spent a few hours looking through the source code of JasperReports to get to the following conclusions (which I hope will be helpful to anyone having the same problem):

    There are at least four ways in which you can use some kind of relative paths in your reports (for images or for subreports):

    1) The simplest way is to put the .jrxml + .jasper + image files in the classpath, because the default implementation looks at some point in the classpath to find the needed files.
    You can even put them in a subfolder in the classpath (like "reports/mysubreport.jasper") and specify it in the main report like this:
    Code:
    <defaultValueExpression ><![CDATA["reports/mysubreport.jasper"]]></defaultValueExpression>
    2) Another option is when you call JasperFillManager.fillReport(jasperReport, parameters, ...), to put in the parameters map the folder that contains the reports, either as String or as File:
    Code:
    String reportsDirPath = context.getRealPath("/reports/");
    parameters.put("reportsDirPath", reportsDirPath);
    
    <parameter name="reportsDirPath" class="java.lang.String" isForPrompting="false"/>
    <imageExpression class="java.io.File"><![CDATA[new File($P{reportsDirPath}, "images/logo.jpg")]]></imageExpression>
    <subreportExpression class="java.io.File"><![CDATA[new File($P{reportsDirPath}, "mysubreport.jasper")]]></subreportExpression>
    or

    Code:
    String reportsDirPath = context.getRealPath("/reports/");
    File reportsDir = new File(reportsDirPath);
    if (!reportsDir.exists()) {
        throw new FileNotFoundException(String.valueOf(reportsDir));
    }
    parameters.put("reportsDir", reportsDir);
    
    <parameter name="reportsDir" class="java.io.File" isForPrompting="false"/>
    <imageExpression class="java.io.File"><![CDATA[new File($P{reportsDir}, "images/logo.jpg")]]></imageExpression>
    <subreportExpression class="java.io.File"><![CDATA[new File($P{reportsDir}, "mysubreport.jasper")]]></subreportExpression>
    3) Yet another option is to pass directly the compiled (and loaded) sub-report object (but this will not take care of your embedded images):

    Code:
    String reportFileNameSource = context.getRealPath("/reports/" + reportName + ".jrxml");
    String reportFileName = context.getRealPath("/reports/" + reportName + ".jasper");
    // Compile report if needed
    File reportFileSource = new File(reportFileNameSource);//  /reports/WebappReport.jrxml
    if (!reportFileSource.exists()) {
        throw new FileNotFoundException(String.valueOf(reportFileSource));
    }
    File reportFile = new File(reportFileName);//  /reports/WebappReport.jasper
    if (!reportFile.exists() || reportFileSource.lastModified() > reportFile.lastModified()) {
        log.debug("Compiling report design " + reportFileNameSource + " to report file " + reportFileName);
        JasperCompileManager.compileReportToFile(reportFileNameSource, reportFileName);
        reportFile = new File(reportFileName);
    }
    log.debug("Loading report from file " + reportFile.getPath());
    JasperReport mysubreport = (JasperReport)JRLoader.loadObject(reportFile.getPath());
    parameters.put("mysubreport", mysubreport);
    
    <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{mysubreport}]]></subreportExpression>

    4) And finally, and probably the best option is to put in your parameters map an instance of a FileResolver that will allow JasperReports to find the files in the folder where they are placed, like this:
    Code:
    String reportsDirPath = context.getRealPath("/reports/");
    File reportsDir = new File(reportsDirPath);
    if (!reportsDir.exists()) {
        throw new FileNotFoundException(String.valueOf(reportsDir));
    }
    parameters.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(reportsDir));
    
    
    <imageExpression class="java.lang.String"><![CDATA["images/logo.jpg"]]></imageExpression>
    <subreportExpression class="java.lang.String"><![CDATA["mysubreport.jasper"]]></subreportExpression>
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2009
    Posts
    1
    Rep Power
    0

    Last solution is not working


    Hello,

    I tried your last solution. The REPORT_FILE_RESOLVER is now correctly set but when I call the report from my web application, it still can't find the supreport. That's why the path to the subreport does still not include the path of the file resolver. How could Jasper detect that all paths in the template (compiled template) have to be replaced / extended by the file resolver path? Must the file name include something like $P{REPORT_FILE_RESOLVER}.resolveFile(<Subreport name>)?

    thx
    tomcat17
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    4
    Rep Power
    0

    Exclamation


    Originally Posted by tomcat17
    Hello,

    I tried your last solution. The REPORT_FILE_RESOLVER is now correctly set but when I call the report from my web application, it still can't find the supreport. That's why the path to the subreport does still not include the path of the file resolver. How could Jasper detect that all paths in the template (compiled template) have to be replaced / extended by the file resolver path? Must the file name include something like $P{REPORT_FILE_RESOLVER}.resolveFile(<Subreport name>)?

    thx
    tomcat17
    No, the file resolver is not some kind of "parent path". You must not put $P{REPORT_FILE_RESOLVER}.resolveFile....
    The file resolver is simply a class that will be called automatically by jasper when filling the report, to let the file resolver search for files in other places.

    Have you put in your java code (that calls Jasper to fill the report) the following lines?

    Code:
    parameters.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(new File(context.getRealPath("/reports/"))));
    If so, then make sure that the report (and especially the compiled report my_report.jasper) is placed in a directory called "/reports" that is located in the root of the web application (alongside your "/images" or "/css" directory, for example).

    Alternatively, you can put my_report.jasper in /WEB-INF/reports and use:

    Code:
    parameters.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(new File(context.getRealPath("/WEB-INF/reports/"))));
    OR put my_report.jasper in /WEB-INF/classes/reports and use:

    Code:
    parameters.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(new File(context.getRealPath("/WEB-INF/classes/reports/"))));

    This last case is actually my number 1) suggestion from the previous post. In this last case you don't even need to configure a FileResolver, because jasper's default file resolver looks in the classpath.

    And moreover, I definitely recommend this last approach, to just put your reports/subreports/reportimages in the classpath (inside "/WEB-INF/classes/reports"), because in this way you don't need to configure any file resolver, AND because context.getRealPath() does not work inside .war files!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2007
    Posts
    12
    Rep Power
    0

    Dear All,


    Dear All,
    I am new to jasper report.Any body know how to add the subreport within another supreport if its possible.Can you send me sample xml code.Im waiting for your.Advance thanks to you
    Thanks & Regards
    Siva
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    4
    Rep Power
    0

    Arrow Easiest way to use subreports in Jasper Reports


    Dear Siva,

    The easiest way to use subreports in Jasper Reports is to put the compiled subreport in some path located in the classpath (for example: /WEB-INF/classes/jasperreports/mySubReport.jasper)

    Then inside the master report design (mainReport.jrxml) you just put the following lines:

    <parameter name="MySubReport" isForPrompting="false" class="java.lang.String">
    <defaultValueExpression ><![CDATA["jasperreports/mySubReport.jasper"]]></defaultValueExpression>
    </parameter>

    The compiled report for the master report will be located, for example, at /WEB-INF/classes/jasperreports/mainReport.jasper
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2008
    Posts
    3
    Rep Power
    0
    anyone know how I can do this on UNIX?

    I have my report, jrxml file in directory abc and have my image file in the same directory.

    I've tried all the following method but with no success.

    <imageExpression class="java.lang.String"><![CDATA["/abc.jpg"]]></imageExpression>
    <imageExpression class="java.lang.String"><![CDATA["\/abc.jpg"]]></imageExpression>

    * this work in my PC but not on our unix server.
    <imageExpression class="java.lang.String"><![CDATA["\\abc.jpg"]]></imageExpression>

    Any input?
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2014
    Posts
    1
    Rep Power
    0
    hi
    i'm new in jasper
    i create a report that it have 3 subreports, & it work well
    but when i run it in another computer, there is sum errors in it
    "Resource*not*found*at*:*C:\Users\Barband\Desktop\Fish\report3_subreport1.jasper"
    this is address of the reports on main computer
    what should i do?!
    can i give the path parametere & it work on another computer?!
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    4
    Rep Power
    0

    Remove the absolute path from your JRXML file


    Originally Posted by Farfalla
    hi
    i'm new in jasper
    i create a report that it have 3 subreports, & it work well
    but when i run it in another computer, there is sum errors in it
    "Resource*not*found*at*:*C:\Users\Barband\Desktop\Fish\report3_subreport1.jasper"
    this is address of the reports on main computer
    what should i do?!
    can i give the path parametere & it work on another computer?!
    Dear Farfalla,
    As mentioned above, do not use an absolute path for the subreport, but you need to make sure (at build and runtime) to put the compiled report and subreport (.jasper files) in the classpath of your java application, and use the classpath-relative path to the subreport.

    For example in your case, if you put both reports in the same location, the the easiest is actually to specify the relative path of the subreport (relative to the main report). So basically you can just edit your JRXML file and replace the full-path
    Code:
    <subreportExpression class="java.lang.String"><![CDATA["C:\Users\Barband\Desktop\Fish\report3_subreport1.jasper"]]></subreportExpression>
    with the relative path:
    Code:
    <subreportExpression class="java.lang.String"><![CDATA["report3_subreport1"]]></subreportExpression>
    From what I remember, the problem usually is that when you use iReport to create and edit your reports, it automatically puts the absolute path (with C:\Users\Barband\Desktop\Fish\...) for the subreport, which is not good.. You have to edit the jrxml file (maybe in notepad++) to remove the absolute path.

IMN logo majestic logo threadwatch logo seochat tools logo