Question
· Jun 25, 2018

Generating PDF with tables programmatically

I have this local, containing a list of books of arbitrary length:

set books=2
set books(1, "author") = "Alice"
set books(1, "title") = "Hello"
set books(1, "pages") = "123"
set books(2, "author") = "Bob"
set books(2, "title") = "World"
set books(2, "pages") = "456"

And I want to generate this PDF (there could be more than two tables), each book is a separate table:

The header is always the same (Author, Title, Page) but the number of tables would be different.

ZEN reports sounds relevant, but I'm not sure how to pass data from local there and how to draw a separate table for each result.

Or there is some other solution?

Discussion (3)1
Log in or sign up to continue

So far I got:

Class Test.Zen Extends %ZEN.Report.reportPage
{

Parameter DEFAULTMODE = "pdf";

/// ReportDefinition is a placeholder.
XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition" ]
{
<report xmlns="http://www.intersystems.com/zen/report/definition"
    name="MyReport" runonce="true">
  </report>
}

XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display" ]
{
<report xmlns="http://www.intersystems.com/zen/report/display"
name="MyReport">
<body>
<table ongetData="GetCount">
<table orient="row" ongetData="NamesAndAddresses" style="border:1pt solid black">
<parameter fieldnum="1"/>
<item fieldnum="1" >
<caption value="Name"/>
</item>
<item fieldnum="2" >
<caption value="Title" />
</item>
<item fieldnum="3" >
<caption value="Pages" />
</item>
</table>
<parameter value="test" />
</table>
</body>
</report>
}

ClassMethod GetCount(ByRef var As %String, ByRef params)
{
    set count=3
    for i=0:1:count-1 {
        set var(i, 0) = i
    }
}

Method NamesAndAddresses(ByRef var As %String, ByRef params)
{
    if (params(1) = 0) {
       Set var(0,0) = "Alice"
       Set var(0,1) = "Hello"
       Set var(0,2) = 123
    } elseif (params(1) = 1) {
       Set var(0,0) = "Bob"
       Set var(0,1) = "World"
       Set var(0,2) = 456
    } elseif (params(1) = 2) {
       Set var(0,0) = "Charlie"
       Set var(0,1) = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
       Set var(0,2) = 789
    }
}

}

Which produces this output:

 

The questions I have:

  1. Is there a way to add breaks between "rows"?
  2. How do I add inside table borders?
  3. How do I give 10% of width to Name/Page/Title and the rest to values?
  4. How do I auto-break long strings into several?

Here is a similar example:

===============================================================================================

/// Created using the page template: Default
Class VICS.Reports.MZenR2 Extends %ZEN.Component.page
{

/// Class name of application this page belongs to.
Parameter APPLICATION;

/// Displayed name of this page.
Parameter PAGENAME = "MZenR2";

/// Domain used for localization.
Parameter DOMAIN;

/// This Style block contains page-specific CSS style definitions.
XData Style
{
<style type="text/css">
</style>
}

/// This XML block defines the contents of this page.
XData Contents [ XMLNamespace = "http://www.intersystems.com/zen]
{
<page xmlns="http://www.intersystems.com/zentitle="">
<button caption="Run Report" onclick="zenPage.runReport();/>
</page>
}

/// This class method callback is called just before the server-side page
/// object is created.
ClassMethod %OnBeforeCreatePage() As %Status
{
For = 1:1:9 {
Set list1 = $LB("John","Jack","Jim","Joanne","Jen","Jill","Paul","Will","Roger")
Set list2 = $LB("Adams","Anderson","Allen","Nelson","Jenkins","Rotterman","Emerson","Wilson","Jackson")
FirstName=$LG(list1,+i)
LastName=$LG(list2,+i)
Name=FirstName_" "_LastName
Company="Alpha "_i
Email=FirstName_"123@gmail.com"
PhoneWork="(111) 222 333"_i
Note="aaaaaaaa"_i
Set ^testMprint1(i) = Name_"|"_Company_"|"_Email_"|"_PhoneWork_"|"_Note_"|"
}
Quit $$$OK
}

ClientMethod runReport() [ Language = javascript ]
{
  var x zenPage.launchPopupWindow(zenLink('VICS.Reports.MReportPDF2.cls'));
}

}
--------------------------------------------------------------------------------------------------------------------------------------------

Class VICS.Reports.MReportPDF2 Extends %ZEN.Report.reportPage
{

Parameter DEFAULTMODE = "pdf";

/// XML that defines the contents of this report.
XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition]
{
<report xmlns="http://www.intersystems.com/zen/report/definition"
name='myReport' call="CreateXML">

</report>
}

XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display]
{
<report xmlns="http://www.intersystems.com/zen/report/display
  name='myReport' title='HelpDesk Sales Report' style='standard'>
  <pagemaster>
    <masterreference masterReference="first" pagePosition="first">
      <document width="8.5in" height="11in" marginLeft="1.25in" 
        marginRight="1.25in" marginTop="1.0in" 
        marginBottom="1.0in" headerHeight="2.0in"></document>
      <pageheader>
        <class="banner1">Mumps Zen Report</p>
      </pageheader>
    </masterreference>
    <masterreference masterReference="rest" pagePosition="rest">
      <document width="8.5in" height="11in" marginLeft="1.25in" 
        marginRight="1.25in" marginTop="1.0in" 
        marginBottom="1.0in" headerHeight=".75in"></document>
      <pageheader>
        <table orient="col" layout="fixed" width="6in">
          <item style="text-align:left" value="Mumps Zen Report" />
          <item style="text-align:right" special="page-number-of" />
        </table>
      </pageheader>
    </masterreference>
  </pagemaster>
 <body >
<!-- MAIN REPORT GROUP -->
<group name="PersonGroup">
<table orient="row" width="3in" class="table4" altcolor="#DFDFFF">
        <item field="Name" width="2in">
          <caption value="Name:" width="2in"/>
        </item>
        <item field="Company" width="2in">
          <caption value="Company:" width="2in"/>
        </item>
         <item field="Email" width="2in">
          <caption value="Email:" width="2in"/>
        </item>
        <item field="PhoneWork" width="2in">
          <caption value="Work Phone:" width="2in"/>
        </item>
        <item field="Note">
          <caption value="Note:"/>
        </item>
      </table>
      </group>
 </body>
</report>
}

ClassMethod CreateXML()
{
    n=""
1 n=$o(^testMprint1(n)) q:n=""
Name=$p(^testMprint1(n),"|",1)
Company=$p(^testMprint1(n),"|",2)
Email=$p(^testMprint1(n),"|",3)
PhoneWork=$p(^testMprint1(n),"|",4)
Note=$p(^testMprint1(n),"|",5)
    !,"<PersonGroup>"
!,"<Name>",Name,"</Name>"
!,"<Company>",Company,"</Company>"
!,"<Email>",Email,"</Email>"
!,"<PhoneWork>",PhoneWork,"</PhoneWork>"
!,"<Note>",Note,"</Note>"
    !,"</PersonGroup>"
    1
}

}
=======================================================================================