Question
· Aug 9, 2021

Dynamically create tables in ZEN PDF report

Dear Developers,

I have a complex ZEN PDF report that has multiple tables that essentially are the same but are populated by different global definitions. The code has hardcoded groups for these tables but I would like the number of tables to be variable as many as there are global levels for a particular report.

Is there any way that I could build a report from a variable source of data rather that hardcoding 10 or more exact sections like the code below ? 

The code below is for table 2 in my report

<container ifexpression="%report.TestProfileFlag(2)=1">
<pagebreak ifexpression="%report.PageBeforeTestProfile(2)=1"></pagebreak>
<table orient="col" class="borderless" width='#($g(^||Page("TotalRowWidth")))#in' group="TestTable2">
<table orient="row" caption='#(..Header("TestProfile",2))#' style='#(..Style("TestProfileHeader",2))#' width='#($g(^||Page("TotalRowWidth")))#in'>
<table orient="col" class="default" style='#(..Style("TestProfileSubHeader",2))#' width='#($g(^||Page("TotalRowWidth")))#in' group="TestData">
<item field="TestColumn1" width='#(..TestColumnWidth(2,1))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra1" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,1))#'/></item>
<item field="TestColumn2" width='#(..TestColumnWidth(2,2))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra2" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,2))#'/></item>
<item field="TestColumn3" width='#(..TestColumnWidth(2,3))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra3" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,3))#'/></item>
<item field="TestColumn4" width='#(..TestColumnWidth(2,4))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra4" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,4))#'/></item>
<item field="TestColumn5" width='#(..TestColumnWidth(2,5))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra5" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,5))#'/></item>
<item field="TestColumn6" width='#(..TestColumnWidth(2,6))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra6" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,6))#'/></item>
<item field="TestColumn7" width='#(..TestColumnWidth(2,7))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra7" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,7))#'/></item>
<item field="TestColumn8" width='#(..TestColumnWidth(2,8))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra8" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,8))#'/></item>
<item field="TestColumn9" width='#(..TestColumnWidth(2,9))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra9" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,9))#'/></item>
<item field="TestColumn10" width='#(..TestColumnWidth(2,10))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra10" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,10))#'/></item>
<item field="TestColumn11" width='#(..TestColumnWidth(2,11))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra11" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,11))#'/></item>
<item field="TestColumn12" width='#(..TestColumnWidth(2,12))#in' style='#(..Style("TestProfileCell",2))#' stylecall="HighLight" styleparams="Zebra12" styleparamNames="Value"><caption style='#(..Style("TestProfileCaption",2))#' value='#(..Caption("TestProfile",2,12))#'/></item>
</table>
</table>
</table>
<container ifexpression="%report.TestProfileImage(2)=1">
<table orient="col" class="borderless" width='#($g(^||Page("TotalRowWidth")))#in' group="TestTable2">
<table orient="row" width='#($g(^||Page("TotalRowWidth")))#in'>
<table orient="col" class="default" width='#($g(^||Page("TotalRowWidth")))#in' group="TestData">
<block>
<img src='!Image' contentHeight='!ImageHeight' contentWidth='!ImageWidth' height='!ImageHeight' width='#(..TestColumnWidth(2,1))#in' style='#(..Style("TestImage"))#' includeColUnlessXPath='TestData[Image=""]'></img>
</block>
</table>
</table>
</table>
</container>
<pagebreak ifexpression="%report.PageAfterTestProfile(2)=1"></pagebreak>
</container>

Product version: Caché 2018.1
Discussion (1)1
Log in or sign up to continue

Hello,

Since you are talking about the same structure but coming from different elements - you could create a composite that you can then pass different to.

So for example I have a specific layout for address in a report - I create a composite for it

Class Julie.Reports.Composite.AddressBlock Extends %ZEN.Report.Display.composite
{
Property AddressLine1 As %ZEN.Datatype.string;

Property AddressLine2 As %ZEN.Datatype.string;

Property Town As %ZEN.Datatype.string;

XData Display [ XMLNamespace = "http://www.intersystems.com/zen/report/display]
{
<composite xmlns="http://www.intersystems.com/zen/report/display"
xmlns:julie=http://www.intersystems.com/zen/report/display/JULIE>

<block ifxexpression="#(..AddressLine1)#">
<item field="#(..AddressLine1)#" too-long-text="wrap"/>
<br/>
</block>
<block ifxexpression="#(..AddressLine2)#">
<item field="#(..AddressLine2)#" too-long-text="wrap"/>
<br/>
</block>
<block ifxexpression="#(..Town)#">
<item field="#(..Town)#" too-long-text="wrap"/>
<br/>
</block>
</composite>
} }

Then in the actual report I would call the composite passing the report elements to the appropriate composite property:

<julie:AddressBlock width="12%" AddressLine1="AddressLine1" AddressLine2="AddressLine2" Town="AddressCity"/>

<julie:AddressBlock width="12%" AddressLine1="CustomerLine1" AddressLine2="CustomerLine2" Town="CustomerCity"/>

Thanks Julie