You are on page 1of 11

First Page Header

1. Repeatable Row Headers


If your invoices break across a page and you want to repeat the column header row this can be
achieved using MSWords functionality.
1. Highlight the header row
. !able " !able #roperties
$. %nder the &ow tab select the '&epeat as Header row at the top of each page
If the invoices table breaks across a page the header row will be repeated.
2. Splitting Rows across pages
(ou can prevent rows splitting across a page break by using MSWords functionality)
1. Highlight the data row
2. !able " !able #roperties
3. %nder the &ow tab deselect the '*llow row to break across pages
&ows that would normally be split across two pages will now be moved to the second page to
preserve the row data.
3. Format Number:
+,format-number./0!1*M!2342444.5536,"
+7sl)decimal-format name83/uro3 decimal-separator8323 grouping-separator83.3
7dofo)ct783begin39"
4. Re-Grouping !"
/7)
S%##:I/&S
I0;<I=/S
#o
S%##:I/&S
=%&&/0=(
I0;<I=/S
S$nta%) for-each-group)>1I0;<I=/10%M?I0;<I=/1=%&&/0=(1=<@/
!his is specifying that we want to create a new group 'I0;<I=/1=%&&/0=(1=<@/ based on
the original '>1I0;<I=/10%M group. We then have the currency label9value pair2 the invoice
table then follows2 inside the >rp)Invoice field we now have 'for-each)current-group.6 to refer to
the new I0;<I=/1=%&&/0=(1=<@/ group we have Aust created. 0ote) we cannot refer to the
group as I0;<I=/1=%&&/0=(1=<@/ as this group is only created at runtime.
So now we have a new grouping we can create summary totals at this level to generate totals per
currency2 inside the new fields we have sum.current-group.69/0!1*M!6 for the entered amount2
again we use the current-group.6 tag to refer to the new 'I0;<I=/1=%&&/0=(1=<@/ group.
>rp)Supplier@ecimal Bormat
Supplier Supplier 1
&ddress 1 :ong *venue
&e>rp)=urr 'urrenc$: %S@
First Page Footer
This is the first section header
/nd =urr
#otal (or Supplier: Supplier 1 12555.55 12555.55
/nd Supplier
). *ariables:
InitialiCing the variable)
+,7do7slt)set1variable.D1E@<=!E2 F7F2 16," +,7do7slt)get1variable.D1E@<=!E2 F7F6,"
%sing the variable value and placing the result in the same variable)
+,7do7slt)set1variable.D1E@<=!E2 F7F2 7do7slt)get1variable.D1E@<=!E2 F7F6G156,"+,
7do7slt)get1variable.D1E@<=!E2 F7F6,"
+. Running #otal) %sing variables to create a running total column to the template
&!ot;ar
Invoice
0umber
Inovice *mount &unning
!otal
>rp) Invoice1$- D155.55 D155.55
Here the running amount is the line by line summation of Invoice amount till that point.
,. Page Total
a. Add page total:
+,add-page-total)pt?F*==!@1*M!F,"
b. Show page total:
+,show-page-total)pt?F42445.55F,"
In the above e7amples 'pt refers to page count. We can use any variable to refer the count.
-. 'onditional Hig.lig.ting wit. #e%t /ecoration
Setting font to bold if invoice amount greater than 1555.
+,if)*==!@1*M!"1555,"+7sl)attribute 7dofo)ct783block3 name83font-
weight3"bold+97sl)attribute"+,end if,"
Setting background color to green if invoice amount greater than 1555.
+,if)*==!@1*M!"1555,"+7sl)attribute 7dofo)ct783block3 name83background-
color3"lime+97sl)attribute"+,end if,"
0. Repeating Header:
1n2oice Num #$pe 1n2oice /ate G" /ate 3ntered &mt &ccounted &mt
>rp)Invoice11$HI Standard 1-Jan-55H 1-Jan-55H 1555.55 1555.55/nd
Invoice
#otal (or %S@ 1555.55 1555.55
This is the first section header
Maintaining header information across pages and resetting the page numbering for each new
header
%se (or-eac.4section to repeat the header information across pages of the output document.
Bor e7ample)
Bor each customer
Bor each currency code
Bor each Invoice K @isplay invoice details
In this case the =ustomer 0ame will be repeated if the line information runs across more than
one page2 the page numbering will also be reset.
15. 6Fwd-'Fwd)
*dding a brought forward9carried forward field to a template field
@efine brought forward in the header part and carried forward in the footer part.
=arried forward is the sum of previous page amount and present page amount where as brought
forward is the previous page carried forward amount.
+,template)header,"
1n2oice "isting Report
1555 1555
+,end template ,"
+,template)footer,"
#age !otal) 1555 1555
1555 1555
+,end template,"
Init #!s
Invoice
!ype
Invoice
0umber
Invoice
@ate
Invoice
=urrency
/ntered
*mount
*ccounted
*mount
B/ I0;1!(#/ 1$$H 15-May-
55L
%S@ 12555.55 12555.55 />
/nd #!s
In the above e7ample we can see the brought forward defined for entered amount and accounted
amount in the template header and carried forward in the footer section.
/7ample output)
BFWCFWD.pdf
11. /$namic 'olumns) !emplate to handle data columns when the number of them is
unknown at runtime.
Dynamic Data Columns
This is the first section header
When the EM: columns in the data are dynamic .that is2 the number of columns can vary6 the
following four tags can be used in a template to accommodate the dynamic formatting reMuired to
render the data correctly.
@ynamic =olumn Header +,splitKcolumnKheader)name,"
%se this tag to define which group to split for the column headers of a table.
@ynamic =olumn +,splitKcolumnKdata)name,"
%se this tag to define which group to split for the column data of a table.
@ynamic =olumn Width +,splitKcolumnKwidth)name,"
%se this tag to define the width of the column2 if you have an element strong the specific
width for a column use this tag to define it.
@ynamic =olumn Widths unit value .in points6 +,splitKcolumnKwidthKunit)value,"
%se this tag to define a multiplier for the column width i.e if your column width are defined
in character cells then you will need a multiplier value NO to render the columns to the
correct width in points. If the multiplier is not defined2 the widths of the columns are
calculated as a percentage of the total width of the table. See the following e7ample)
'olumn 1 'olumn 2 'olumn 3
Width 15 1 1H
Multiplier not present -
Pwidth
159.15G1G1H6Q155
8 RP
$$P $IP
Multiplier 8 O K Width O5pts Spts RHpts
HoriContal table break with row header number +,horiContalKbreakKtable)number,"
'olumn 1 'olumn 2 'olumn 3
Width 15 1 1H
Multiplier not present -
Pwidth
159.15G1G1H6Q155
8 RP
$$P $IP
Multiplier 8 O K Width O5pts Spts RHpts
/7ample !emplate2 Eml data and <utput)
+,7ml version831.53 encoding83utf-R3 ,"
+!estScore!able"
+!estScores"
+!est=ategory"!at.ematics+9!est=ategory"
+!estScore width831)3"
+!estScore&ange"5-25+9!estScore&ange"
+0um<fStudents"35+90um<fStudents"
+9!estScore"
+!estScore width83253"
+!estScore&ange"21-45+9!estScore&ange"
+0um<fStudents"4)+90um<fStudents"
+9!estScore"
+!estScore width831)3"
+!estScore&ange"41-+5+9!estScore&ange"
+0um<fStudents")5+90um<fStudents"
+9!estScore"
+!estScore width83253"
+!estScore&ange"+1--5+9!estScore&ange"
+0um<fStudents"152+90um<fStudents"
+9!estScore"
+!estScore width831)3"
+!estScore&ange"-1-155+9!estScore&ange"
+0um<fStudents"22+90um<fStudents"
This is the first section header
+9!estScore"
+9!estScores"
</TestScoreTable>
<utput and the tags are e7plained in the below section. Here we are selecting L ranges of marks
and if we want to change the range then automatically the columns will be displayed in the output
with the new range because we are using split at the column header level.
+,split-column-header)!estScore," - split the !estScore
col
+,split-column-width)Twidth," - set the width for the
column
+,!estScore&ange,"P - placeholder for P value heading
#estScore Row Header and Splitting
=olumn Header and >roups =ontent and Splitting
+,for-each)!estScores," - Start the !estScores group
+,!est=ategory," - placeholder for category name i.e.
Mathematics
+,split-column-data)!estScore," - split the
!estScore column
+,0um<fStudents," - placeholder for 4 of students
in this range
+,end," - end of group
!he above template will render the following result in the output)
#estScore 5-25 21-45 41-+5 +1--5 -1-155
Mathematics $5 HL L5 15
12. "ast 7age:
%sed to display first9last page header when only one page is generated.
!his e7ample shows the first9last page header9footer if only 1 page is generated.
B
;endor);/0@<&10*M/
*ddress) *@@&/SS
1n2oice #$pe 1n2oice Num 1n2oice /ate 1n2oice
'urrenc$
3ntered
&mount
&ccounted
&mount
B Invoice 15555 51-Jan-55O %S@ 155 155 /
/
This is the first section header
:ast #age Header
:ast #age Uody
#a% Summar$
#a% 'ode 3ntered &mount &ccounted &mount
B ;*! 1R.L 155 155/
!he synta7 in the :ast #age Uody changes)
+,startTlast-page-first)body,"+,end body," for last page header and
+,startTlast-page)body,"+,end body," for first page header display.
/ispla$ing 'ompan$ logo image d$namicall$ in !" 7ublis.er 861
#ools9 in R#F #emplate :
1. Insert any dummy placeholder image in &!B template .Insert V#icture6
. &ight click on image and click WSiCeX then goto W*lt!e7tX tab and enter dynamic path in
W*lternative !e7tX field e.g. url)Yconcat.'DY<*1M/@I*Z29EE1:ogo.Apg6Z.
D<*1M/@I* path !<# is actual path in <racle *pp instance where images are stored . @U* may
help to get D<*1M/@I* !op path to upload EE1:ogo.Apg file.
/ispla$ing signature d$namicall$ in !" 7ublis.er 861 tolls9 R#F
template
1. Insert any dummy placeholder image in &!B template .Insert V#icture6
. &ight click on image and click WSiCeX then goto W*lt!e7tX tab and enter dynamic path in
W*lternative !e7tX field e.g. url)Yconcat.'D
Y<*1M/@I*Z9EE1buyer129#<1@*!*9@<=%M/0!1U%(/&1BI&S!10*M/ 2129#<1@*!*9@
<=%M/0!1U%(/&1:*S!10*M/ 2.Apg6Z
D<*1M/@I* path !<# is actual path in <racle *pp instance where images are stored. @U* may
help to get D<*1M/@I* !op path to upload buyers signature file. Uelow e7amples will
demonstrate displaying image dynamically in EM: publisher in Microsoft <ffice 55$ which
obsolete in MS office 55S and onward versions.
This is the first section header
#o .andle parameteri:ed la$out
If the requirement is to display a diferent layout based on a user parameter
value or a List of Value selection, then the parameter can be passed to RTF
layout and conditionally display the layout.
On the Report ditor you !rst need to de!ne a parameter "ith name
#ept$ame. If this parameter has to be associated "ith a List of Value %LOV&,
then create a LOV on the Report ditor pa'e. $e(t, in the parameter
de!nition select parameter type as )*enu+ and then select the LOV from the
selection.
In the RTF template de!ne a parameter usin' synta( ,
-.param/be'in0#ept$ame.1
$o" "hen user selects a department name from the List of Value on the
report vie"er pa'e, the value 'ets passed to RTF layer into the #ept$ame
parameter. To display the layout based on this user selection, you can use an
IF statement or a 23OO4 statement to evaluate the parameter value and
call the associated sub template. 5se 23OO4 statement "hen too many
conditional tests are to be done and a default action is e(pected for rest of
the values, for e(ample, for each department here "e have a diferent sub
template and if the user parameter has a department name "ith no
associated sub template, then a default sub template can be called in
other"ise section. For more information on 23OO4 statement, chec6 the
BI Publisher Report Designers Guide.
<?choose:?>
<?when:$DeptName=Accounting?><?call:tAcc?>
<?end when?>
<?when:$DeptName=Sales?><?call:tSales?>
<?end when?>
<?when:$DeptName=Marketing?><?call:tMark?>
<?end when?>
<?otherwise:?><?call:tDeault?>
<end otherwise>
<?end choose?>
This is the first section header
!ere all the templates in su" template # tAcc$ tSales$ tMark and
tDeault # are deined in one %&' ile(
<?template:tAcc?>
###### Accounting )a*out ######
<?end template?>
<?template:tSales?>
###### Sales )a*out ###########
<?end template?>
<?template:tMark?>
###### Marketing )a*out #######
<?end template?>
<?template:tDeault?>
###### Deault )a*out #########
<?end template?>
Bi7ed !able)
&bstract
I was inspired to come up with this because I feel that lots of people want this solution
and they are struggling to implement this.
In this whitepaper2 I am going to e7plain the approach which I used for developing pre-
printed stationary reports by EM: publishers &!B method. !his approach I used for
customers and it works absolutely fine. !hey are very happy. /7ample #re-#rinted
stationary reports which I worked on are following '*# =heck #rinting.Uank6 2*& invoice
#rinting2#< purchase <rder #rinting [. etc[.
6ac;ground
I have a customer who wants to convert their H5G <racle *pps reports to 'EM: publisher
&eports. !hese reports are fall in categories of *& invoice report2 check printing report
and #< print report which they are printing on pre-printed .pre-defined6 stationary.
Just a little background of pre-printed stationary reports layout where there is a fi7
Header section and fi7 @etail Section !able. @etail section table should always have fi7
table height2 in the sense it should always have fi7 number of rows in the table no matter
how many rows returned by actual report run. Bor e7ample Invoice stationary has fi7 $5
rows in line detail table2 and *ctual report run is returning only L rows then rest L blank
rows should be generatedprogrammatically.

So (ar t.ere are solutions a2ailable w.ic. are tal;ing about (i%ing table .eig.t (or
t.e 1
st
pages onwards not (or t.e (irst page itsel(< i.e. w.ere actual report run is
returning lines w.ic. are less t.an lines=(i%ed=per=page. For e%ample 1n2oice run
is returning onl$ ) rows w.ere as pre-printed stationar$ .as (i%ed 35 lines per
page.I struggled a lot to get this solution and now I got this and sharing it in this
whitepaper.

This is the first section header
So far it has not been discovered because of the limitation of for-loop in ES:-B< .EM:
!echnology6.:imitation I mean is 2we can not write loop like ' for .i815?i+1L?iGG6 in EM:.
In EM: 'for loop will always iterate till it gets data2 if we want to go beyond that then we
can not go. I mean we can write for loop based on data value.
!o overcome this problem2 I have used Sub-template concept which I am calling
recursively.

/etail Solution
I am giving this solution for Standard =heck #rinting &eport. !ree structure of data
.Sample EM: data is as follow6.
<LIST_G_CHECKS>
<G_CHECKS> -- Top Most root -- Header
<C_CHECK_!M"E#>$%&'(<)C_CHECK_!M"E#>
<C_*E+,#_!M"E#>$$-.<)C_*E+,#_!M"E#>
<LIST_G_I*,ICES>
<G_I*,ICES> -- Inner loop - L/ne Se0t/on
<C_123MET_!M"E#>%<)C_123MET_!M"E#>
<C_I*,ICE_!M"E#>E#S-$--SE1--4-$56<)C_I*,ICE_!M"E#>
<)G_I*,ICES>
<G_I*,ICES> -- Inner loop - L/ne Se0t/on
<C_123MET_!M"E#>$<)C_123MET_!M"E#>
<C_I*,ICE_!M"E#>E#S-$--SE1--4-$55<)C_I*,ICE_!M"E#>
<)G_I*,ICES>
<)LIST_G_I*,ICES>
<)G_CHECKS>
<)LIST_G_CHECKS>

Uelow is the step-step guide which I follow.

16 <pen the <utermost for loop -- >1=H/=\S
<7for-ea089se0t/on:G_CHECKS7>

6 @eclare >lobal ;ariable called 'no_of_l/nes_per_pa;e -- In this case I have fi7ed H5
lines per page.
<<sl:var/able name=>no_of_l/nes_per_pa;e> sele0t=>number?5-@>)>
This is the first section header

$6 @eclare inconte7t variable for inner group .>1I0;<I=/S62 variable is called
'/nner_;roup
<<sl:var/able <dofo:0t<=>/n0onte<t> name=>/nner_;roupA sele0t=>B))G_I*,ICES>)>

H6 <pen the Inner :oop
<7for-ea08:C/nner_;roup7>

L6 Uefore putting any elements with the help of current record pointer Fposition.62 I am
checking if the current position is moduliCing with the no1of1lines1per1page eMuals Cero
or not. If it reaches the first record after moduliCing then I will create local variable
Ffirst1recF and initialiCe it with F5F.
<7/f:?pos/t/on?@-%@ mod Cno_of_l/nes_per_pa;e=-7><<sl:var/able name=>f/rst_re0>
<dofo:0t<=>/n0onte<t> sele0t=>pos/t/on?@>)>

0ote ) -- *bove $ steps . $2H2L6 are created under D*_/nner_;roup_2nd_*_E/rst_re0
form-field. Here there is limitation of Microsoft-word. We can enter upto 1$R characters
only in 'Status field of '*dd help te7t button.If you want to add more 2 you can do this by
clicking on 'Help \ey which is adAacent to 'Status tab.

O6 If above condition holds true then we will iterate the inner loop.
<7for-ea08:C/nner_;roup7>

S6 I will check with the help of current record pointer Fposition.6F that the current record
position is either greater than Ffirst1recF i.e. the first record or less the
Fno1of1lines1per1pageF value set up earlier. If it is then show the record otherwise not
otherwise it will not go in loop.
<7/f:pos/t/on?@>=Cf/rst_re0 and pos/t/on?@<Cf/rst_re0FCno_of_l/nes_per_pa;e7>

R6 Here I am closing the inner for loop and if condition
<7end /f7><7end for-ea087>

I6 Here 1 am c.ec;ing i( no=o(=lines o( in2oice is moduli:ing wit. t.e
no=o(=lines=per=page e>uals to :ero or not <and t.e same time 1 am c.ec;ing i(
?(irst=rec@?no=o(=lines=per=page is greater t.an no=o(=lines o( in2oice or not.
#.is is important step (or (illing t.e blan; rows.
<7/f:not?0ount?C/nner_;roup@ mod Cno_of_l/nes_per_pa;e=-@ and ?Cf/rst_re0F
Cno_of_l/nes_per_pa;e>0ount?C/nner_;roup@@7>
This is the first section header


156 Now 1 am calling sub-template recursi2el$ (or (illing t.e blan; rows. A.ile
calling t.is template 1 am passing one parameter w.ic. is .a2ing 2alue o(
no=o(=rows to (ill. Sub-template will .a2e Bust one row table.
<<sl:0all-template <dofo:0t<=>/nl/ne> name=>0ountdoGn>><<sl:G/t8-param
name=>0ountdoGn> sele0t=>Cno_of_l/nes_per_pa;e - ?0ount?C/nner_;roup@ mod
Cno_of_l/nes_per_pa;e@>)><)<sl:0all-template>

116 Sub-template declaration
<<sl:template name=>0ountdoGn>>
<<sl:param name=>0ountdoGn>)><<sl:/f test=>C0ountdoGn>><<sl:0all-template
name=>0ountdoGn>><<sl:G/t8-param name=>0ountdoGn> sele0t=>C0ountdoGn - %>)>
<)<sl:0all-template><)<sl:/f>
<)<sl:template>

16 I have created page break after the fi7ed number of rows have been displayed.
<<sl:/f <dofo:0t<=>/nblo0H> test=>Cf/rst_re0F
Cno_of_l/nes_per_pa;e<=0ount?C/nner_;roup@>>
<<sl:attr/bute name=>breaH-before>>pa;e<)<sl:attr/bute>
<)<sl:/f>

1$6 Binally closing outer if and inner for loop and outer for loop.
<7end /f7><7end for-ea087><7end for-ea087>

You might also like