0

Backgroud: Use Java + BIRT to generate report. Generate report in viewer and allow user to choose to export it to different format (pdf, xls, word...).

All program are in "Layout", no program in "Master Page". Have 1 "Data Set". The fields in "Layout" refer to this DS. There is Group in "Layout", gropu by one field. In "Group Header", I create one cell to use as page number. "Page : MyPageNumber". "MyPageNumber" is a field I define which would +1 in Group Header.

Problem: When I use 1st method to generate report, "MyPageNumber" could not show correctly. Because group header only load one time for each group. It would always show 1.

Question: As I know there is "restart page number in group" in Crystal report. How to restart page in BIRT? I want to show data of different group in 1 report file, and the page number start from 1 for each group.

Hunter
  • 11
  • 2
  • 4

2 Answers2

0

Alas, this is not supported with BIRT.

That's probably not the answer you've hoped for, but it's the truth. This is one of the very few aspects where BIRT is way behind other report generator tools.

However, depending on how you have BIRT integrated into your environment, a workaround approach is possible for PDF export that we use in our solution with great success. The idea is to let BIRT generate a PDF outline based on the grouping. And the BIRT report creates information in the ReportContext about where and how it wants the page numbers to be displayed. After BIRT generated the PDF, a custom PDFPostProcessor uses the PDF outline and the information from the ReportContext to add the page numbers with iText. If this work-around is viable for you, feel free to contact me.

hvb
  • 2,484
  • 1
  • 10
  • 13
  • Thank you for your solution. Could I know if your idea to "let BIRT generate a PDF outline based on the grouping" is to use BIRT API to generate PDF? If yes, could you help to share some detail code? Could you help to advise where to use PDFPostProcessor? – Hunter May 04 '15 at 04:49
  • Sorry for this late response: No "programming" needed, it's a feature of the Report Designer IDE: BIRT generates a PDF outline by default automatically if you use groups. The TOC level then represents the nesting level of the groups. You can also add TOC entries manually (see the property "Table of Contents" of layout items). Regarding the PDFPostProcessor: Note that we are not using the WebViewer, instead the PDF generation by BIRT is called with a RunAndRenderTask. After the task has finished, BIRT has generated the PDF. We then modify this PDF using iText. – hvb Aug 10 '15 at 06:35
0

You can do it with BIRT reports using page variables. For example:

  1. Add 2 page variables... Group_page, Group_name.
  2. Add 1 report variable... Group_total_page.
  3. In the report beforeFactory add the script:

    prevGroupKey = "";
    groupPageNumber = 1;
    reportContext.setGlobalVariable("gGROUP_NAME", "");
    reportContext.setGlobalVariable("gGROUP_PAGE", 1);
    
  4. In the report onPageEnd add the script:

    var groupKey = currGroup; 
    var prevGroupKey = reportContext.getGlobalVariable("gGROUP_NAME");
    var groupPageNumber = reportContext.getGlobalVariable("gGROUP_PAGE");
    if( prevGroupKey == null ){
        prevGroupKey = "";
    }
    
    if (prevGroupKey == groupKey)
    {
     if (groupPageNumber != null)
    {
        groupPageNumber = parseInt(groupPageNumber) + 1;
    }
    else {
        groupPageNumber = 1;
    }
    }
    else {
        groupPageNumber = 1;
        prevGroupKey = groupKey;
    }
    reportContext.setPageVariable("GROUP_NAME", groupKey);
    reportContext.setPageVariable("GROUP_PAGE", groupPageNumber);
    reportContext.setGlobalVariable("gGROUP_NAME", groupKey);
    reportContext.setGlobalVariable("gGROUP_PAGE", groupPageNumber);
    
    var groupTotalPage = reportContext.getPageVariable("GROUP_TOTAL_PAGE");
    if (groupTotalPage == null)
    {
        groupTotalPage = new java.util.HashMap();
        reportContext.setPageVariable("GROUP_TOTAL_PAGE", groupTotalPage);
    }
    groupTotalPage.put(groupKey, groupPageNumber);
    
  5. In a master page onRender script add the following script:

    var totalPage = reportContext.getPageVariable("GROUP_TOTAL_PAGE");
    var groupName = reportContext.getPageVariable("GROUP_NAME");
    if (totalPage != null)
    { 
        this.text = java.lang.Integer.toString(totalPage.get(groupName));
    }
    
  6. In the table group header onCreate event, add the following script, replacing 'COUNTRY' with the name of the column that you are grouping on:

    currGroup = this.getRowData().getColumnValue("COUNTRY");
    
  7. In the master page add a grid to the header or footer and add an autotext variable for Group_page and Group_total_page. Optionally add the page variable for the Group_name as well.

Check out these links for more information about BIRT page variables:

user3660637
  • 624
  • 6
  • 16
  • It should be noted that page variables only work as expected with separate RunTask and RenderTask, which your usually don't want to use because of its negative performance impact and because it obviously has bugs in page-breaking. – hvb Apr 30 '15 at 06:25
  • @user3660637 Thank you for your solution. After apply those code to my BIRT report, it can show total page number of each group when I put "GROUP_PAGE" as in the "Master Page" -> Header -> Grid -> Test (HTML) -> GROUP_PAGE. It still could not show 1, 2, ... for each group. For example, I have 2 groups (Group A has 3 pages, Group B has 2 pages). When I put "GROUP_PAGE" like I mentioned above, I can see 3 in each page of Group A, see 2 in each page of Group B. The page number show as 3, 3, 3, 2, 2. Can you help to advise how to make them to show as 1, 2, 3, 1, 2? – Hunter May 04 '15 at 04:46