0

I am trying to format a report and I have tables that will span multiple pages with various items/fees, and what i would like to do ideally is to display a running total for each page in the table footer, basically i want the sum of the values in my table from the current page back to the first page to display at the bottom. Is there any way to achieve this?

<fo:table width="100%" border-style="groove" border-width="2pt" background-repeat="repeat">
  <fo:table-column column-width="5%" />
  <fo:table-column column-width="60%" />
  <fo:table-column column-width="5%" />
  <fo:table-column column-width="7.5%" />
  <fo:table-column column-width="7.5%" />
  <fo:table-column column-width="7.5%" />
  <fo:table-column column-width="7.5%" />
  <fo:table-footer border-top-style="dashed" border-bottom-style="dashed">
    <fo:table-cell display-align="center">
    </fo:table-cell>
    <fo:table-cell display-align="center">
      <fo:block text-align="center">
        Page <fo:page-number/>
        <xsl:text> OF </xsl:text>
        <fo:page-number-citation ref-id="end" />
      </fo:block>
    </fo:table-cell>
    <fo:table-cell display-align="center">
    </fo:table-cell>
    <fo:table-cell display-align="center">
    </fo:table-cell>
    <fo:table-cell display-align="center">
    </fo:table-cell>
    <fo:table-cell display-align="center">
      <fo:block text-align="end">
        Page Total:
      </fo:block>
    </fo:table-cell>
    <fo:table-cell display-align="center">
    </fo:table-cell>
  </fo:table-footer>
  <fo:table-body>
    <xsl:for-each select="/receipt_invoice/details/product_lot">
      <xsl:variable name="untitled" select="." />
      <fo:table-row>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="right">
            <fo:block>
              <xsl:value-of select="lot/quantity" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block>
            <fo:table width="100%" border-style="none" border-width="2pt" background-repeat="repeat">
              <fo:table-column/>
              <fo:table-column/>
              <fo:table-body>
                <fo:table-row>
                  <fo:table-cell border-style="none" border-width="2pt" padding="2pt" background-repeat="repeat" display-align="before">
                    <fo:block>
                      <fo:block>
                        <xsl:value-of select="product/code" />
                      </fo:block>
                      <fo:block>
                        Lot Qty:
                        <xsl:value-of select="lot/quantity" />
                      </fo:block>
                      <fo:block>
                        <xsl:text>
                          &#xA0;
                        </xsl:text>
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/identifier" />
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/lot_components/component/label" />
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/lot_components/component/value" />
                      </fo:block>
                    </fo:block>
                  </fo:table-cell>
                  <fo:table-cell border-style="none" border-width="2pt" padding="2pt" background-repeat="repeat" display-align="before">
                    <fo:block>
                      <fo:block>
                        <xsl:value-of select="product/first_description" />
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/csd/csd_line" />
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/csd/set_description" />
                      </fo:block>
                      <fo:block>
                        <xsl:value-of select="lot/lot_components/component/label" />
                      </fo:block>
                    </fo:block>
                  </fo:table-cell>
                </fo:table-row>
              </fo:table-body>
            </fo:table>
            Line Number:
            <xsl:value-of select="line_number" />
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="center">
            <fo:block>
              <xsl:value-of select="product/unit_of_measure" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="center">
            <fo:block>
              <xsl:value-of select="stock_charges/storage_rate" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="center">
            <fo:block>
              <xsl:value-of select="stock_charges/storage_amount" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="center">
            <fo:block>
              <xsl:value-of select="stock_charges/handling_rate" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" border-width="1pt" border-color="black" padding="2pt" background-repeat="repeat" display-align="center">
          <fo:block text-align="center">
            <fo:block>
              <xsl:value-of select="stock_charges/handling_amount" />
            </fo:block>
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
    </xsl:for-each>
  </fo:table-body>
</fo:table>

Revision:

So I have decided to use a page footer to display the subtotal on each page, and have set up a marker in my table that simply returns the grand total just to test it out, but now what i was think was that i could try to somehow get the position in my xml file the node was taken from and use something like...

<xsl:value-of select="sum(preceding::value[the_position]"/> 

Where value would actually be the name of the charge being totaled up, is this something that could work? If have been trying different things but I am uncertain of the syntax and how to return the position.

adam5990
  • 346
  • 2
  • 13
  • This sounds like a start: http://stackoverflow.com/questions/7931266/how-can-i-sum-up-some-values-per-page-in-a-table-in-xsl-fo (use ``) – Tomalak Jun 19 '13 at 15:46
  • In the transformation from XML to XSL you can sum previous values (if that data does not exist in your source) and you can put down markers and use retrieve-table-marker (which is an XSL FO 1.1 construct not all FO engines support). You would retrieve the marker into the table-footer. Issues with this is sometimes you do not want it at the table end and using a table footer means you get it (unless of course your FO engine has an option to omit last table footer or something). – Kevin Brown Jun 19 '13 at 22:15
  • Thanks Tomalak, it looks promising at the very least, and thank you also Kevin, unfortunately I am designing my solution to be printed using Apache FOP, which doesn't fully support table footers with multiple columns, and also doesn't support table markers at all, if you know of any work arounds however it would be greatly appreciated. – adam5990 Jun 20 '13 at 18:08
  • 1
    If your rows are of pretty regular height, you can also try the same technique for summation *but* instead put the subtotal table row inside the footer of the page as a single row table. Use the same technique but pull the marker into the footer, not the table-footer with retrieve-table-marker. Careful sizing and you can get it to look just like it is a table footer and you can clear that market at the end of the table so that it does not appear on other pages. – Kevin Brown Jun 20 '13 at 23:42
  • @KevinBrown Thank you, that is actually a really good solution and it seems to work just fine with FOP, cheers! – adam5990 Jun 21 '13 at 15:11

1 Answers1

1

For completeness, posting the description of the solution as an answer.

If your rows are of pretty regular height, you can use sum() function over all previous nodes in your table structure as you output rows and put that running subtotal as a table/table row inside a marker for the footer of the page as a single row table. Retrieve the marker into the page footer (not the table-footer with retrieve-table-marker) using the last one on the page, then clear the marker. Careful sizing and you can get it to look just like it is a table footer and you can clear that marker at the end of the table so that it does not appear on other pages. For the table end, just output the totals.

It may not work with complex tables, especially where there are multi-line rows and keeps on those rows as the table may not reach the footer.

This overcomes two issues (1) you do not need table-markers as many FO engines do not support them (actually there are good reasons for this as they are much more problematic than you think if the content being retrieved could have a large, variable height). And (2) using table-markers can run into issues at the end of the table inside that footer where you may not want it (although you can clear the marker at the last row).

Kevin Brown
  • 8,805
  • 2
  • 20
  • 38