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>
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>