function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AntonyasLenAntonyasLen 

Visualforce Page rendas .pdf tab issue

Dear community,

 

********************************************************************************************

Background:

 

I created a visualforce page for my Quote to get it as pdf.

So far it's working but i got an issue with my QuoteLineItems.( design problem)

********************************************************************************************

In my code i used the apex:repeatas you can see below :

 

 <apex:repeat value="{!Quote.QuoteLineItems}" var="line">
                        <tbody id="lineItem">
                           ****Quote Line Items information are displayed here ****
                        </tbody>
                        
</apex:repeat>  

 The problem come from the number of Quote Line Items, if have two or less items it's fine :

(all the informations are fake information from my sandbox)

 

 

 

Between two and five there is a problem for the price summary:

(all the informations are fake information from my sandbox)

 

With 5 items i don't have any problem :

 

and more than 5 my Quote Line item's tab is dirty:

(all the informations are fake information from my sandbox)

 

I'm not very skilled with this kind of design, so my questions are;

 

Should i created different page depend of the number of my quote line items?
Can we make a count on the visualforce page using apex?

I'm kind a lost .

 

Sincerely,

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Hengky IlawanHengky Ilawan

No problem, nice to see it finally works.

Anyway, it should be fine even if you have 30 or 40 line items. The page break will be inserted nicely at the point as defined in the apex:variable:

 

<apex:variable var="firstPageSize" value="{!5}"/>
<apex:variable var="nextPageSize" value="{!15}"/>

 

Regards,

Hengky

All Answers

Hengky IlawanHengky Ilawan
Hi,

I am not sure this is the best solution, but you can try add in css page-break-before or after property after a certain line of items to force the later line items to appear on the next page.

Regards,
Hengky
AntonyasLenAntonyasLen

Hi,

I'm not very comfortable with css i should put it on my tab or line?

I'll give a look.

 

Thanks

 

AntonyasLenAntonyasLen

Here i'am i tried your idea (it wasn't bad) but it moved my whole tab as you can see:

 

 

Hengky IlawanHengky Ilawan
If your line items couldnot fit into one page, try to close the table after a few items, add the page break property and continue on a new table. That should do the trick.

Regards,
Hengky
AntonyasLenAntonyasLen

how can i close it after after one or two item for example ?


Khaiwong wrote:
If your line items couldnot fit into one page, try to close the table after a few items, add the page break property and continue on a new table. That should do the trick.

Regards,
Hengky

 

Hengky IlawanHengky Ilawan
...
      </td>
   </tr>
</table>
<table style="page-break-before:....>
   <tr>
      <td>
...

 

Regards,

Hengky

AntonyasLenAntonyasLen

sorry my question was for the apex:repeat attribute.

How can i  make just a few line

Hengky IlawanHengky Ilawan

Could you provide some sample codes on how you use the apex:repeat?

 

Regards,

Hengky

AntonyasLenAntonyasLen

you can see below an example ( similar of the example of my first post)

<apex:repeat value="{!Quote.QuoteLineItems}" var="line" >
	<tbody id="lineItem">
		<tr height="18">
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
			<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
			<td valign="top"  style="align:right; padding:4px 3px;"><font size="1" face="Arial"></font></td>
		</tr>
	</tbody>
	<tbody>
		<tr Style="text-align:center;">
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp;  {!ROUND(line.Id_uad__c,0)} </font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; <img src='{!line.URL__c}' style= "height:40px;width:40px;"/></font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Lead_Time__c}</font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Customization__c}</font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Description} </font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!ROUND(line.Quantity,0)} </font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!ROUND(line.UnitPrice,2)} </font></td>
			<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp;  {!ROUND(line.Discount,0)}{!IF((line.Discount>0),'%',' ')} </font></td>
			<td><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:12px;">&nbsp; {!ROUND(line.TotalPrice,2)}</font></td>   
		</tr>
	</tbody>
                        
</apex:repeat>  

 

Hengky IlawanHengky Ilawan

You could wrap the line items using a wrapper class, and you can use something like line type property to differentiate data line and page break.

So your line items would be something like this:

 

data

data

data

pagebreak

data

data

...

data

data

pagebreak

data

data

data

...

 

So, inside your <apex:repeat> you need to make use of the rendered attribute. If the line type is data, show the line item, if line type is pagebreak then show the table close tag.

 

<apex:repeat value="{!WrapLines}" var="line">
  <apex:outputText rendered="{!line.type='DATA'}">
     <tbody id="lineItem">
        ****Quote Line Items information are displayed here ****
     </tbody>
  </apex:outputText>
  <apex:outputText rendered="{!line.type='PAGEBREAK'}">
     </table>
     <table style="page-break-before:always">
  </apex:outputText>
</apex:repeat>  

 I hope you get the idea.

 

Another way to achieve this is to build the complete table string in the controller, and then just output the string in the visualforce page.

 

Regards,

Hengky

 

AntonyasLenAntonyasLen

So my wrapper class will get all the Quote Line Item of my quote on put them into an object (maybe a tab?).

I hope that i understood well, i never did any wrapper class before.

 

Anyway thanks for your help.

 

i will post my solution if it's working.=]

AntonyasLenAntonyasLen

Maybe i'm thinking too much but i read somme example :

here or here.

 

But on my example i need two use a few different kind of item  ( as Quote Opportunity).
So should i wrap with my quote and set an item list? but it's kind a mess for me ...

I'll figure out...

 

 

Sorry and thanks!

 

Hengky IlawanHengky Ilawan

Hi,

 

Sorry about my previous post. To 'close' the table like below will not work because the open and close tags will get mixed up.

  <apex:outputText rendered="{!line.type='PAGEBREAK'}">
     </table>
     <table style="page-break-before:always">
  </apex:outputText>

Anyway, there is another way to achieve this. I just figured out on how to use <apex:variable> as a counter inside the <apex:repeat> loop. You can use the counter as a page break point when it reached a certain number.

This way you don't have to write any wrapper class.

 

Here is the example:

 

<apex:variable var="firstPageSize" value="{!5}"/>
<apex:variable var="nextPageSize" value="{!15}"/>

<apex:variable var="rowNo" value="{!1}"/>

<apex:repeat value="{!Quote.QuoteLineItems}" var="line">
    
    <apex:outputPanel rendered="{!
OR(rowNo=firstPageSize+1, MOD(rowNo-firstPageSize, nextPageSize)=1)}" style="page-break-before:always" layout="block" /> <div style="width:100%; display:table;"> <div style="display:table-row;"> <div style="border-left:1px solid black; border-top:1px solid black; display:table-cell; width:25%">{!line.Description}</div> <div style="border-left:1px solid black; border-top:1px solid black; display:table-cell; width:25%">{!line.Quantity}</div> <div style="border-left:1px solid black; border-top:1px solid black; display:table-cell; width:25%">{!line.UnitPrice}</div> <div style="border-left:1px solid black; border-top:1px solid black; border-right:1px solid black; display:table-cell; width:25%"> {!line.TotalPrice}</div> </div> </div> <apex:variable var="rowNo" value="{!rowNo+1}"/> </apex:repeat>

 

 

Regards,

Hengky

AntonyasLenAntonyasLen

Thanks for you help!!!!!!

 

I got it about the wrapper class but i don't think it's the best answer in my case.

So i tried to use the apex:variable but instead of using div i kep using my table/td/tr and i got this:

so far it's working for my first 5 items but for the others i have to set an others apex:outputPanel rendered for it ???

 

 

 

I think i'm on the good way! Just need to finish it and optimize it!

 

But i set a  style="page-break-before:auto"  on the summary information (after my tab) butthe auto parameter looks like not working very well.

 

anyway THANKS YOU i'm going back to my eclipse . =]

Hengky IlawanHengky Ilawan

The problem when you use TR/TD and <apex:outputPanel> together inside an <apex:repeat> is that the generated table and span/div html tags are overlapping each other, i.e. span/div becomes child node of a table tag, which is invalid.

 

Try to view the HTML source code of the page (change the renderAs to anything but pdf for temporary). I think that was the cause of your current issue with the 2nd page.

 

Regards,

Hengky

AntonyasLenAntonyasLen

Hi,

 

I tried to see my file as an html.

I don't have the problem the break appear.

 

 

 

Here my code:

     <table width="100%" border="0" cellspacing="0" height="350" cellpadding="0" style="border:1px solid #000;page-break-before:auto; ">
     	<apex:variable var="firstPageSize" value="{!5}"/>
	 	<apex:variable var="nextPageSize" value="{!15}"/>
		<apex:variable var="rowNo" value="{!1}"/>
                        <thead>
                            <tr style="bgcolor:#e8e8e8;height:20;">
                                <td valign="bottom" style="width: 10%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 0px 1px 3px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;"> Référence</font> </b></td>
                                <td valign="bottom" style="width: 10%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Visuel *</font> </b></td>
                                <td valign="bottom" style="width: 11%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Délai</font> </b></td>
                                <td valign="bottom" style="width: 16%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Perso.</font> </b></td>
                                <td valign="bottom" style="width: 20%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 0px 1px 3px;text-align:center;"><b> <font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Designation</font></b></td>                                
                                <td valign="bottom" style="width: 8%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Quantité</font> </b></td>
                                <td valign="bottom" style="width: 10%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">PU HT </font></b></td>
                                <td valign="bottom" style="width: 1%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">% Remise</font></b></td>
                                <td valign="bottom" style="width: 14%%; border-right:1px solid #000; border-bottom:1px solid #000; padding:0px 3px 1px 0px;text-align:center;"><b><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:11px;">Montant HT </font></b></td>   
                            </tr>
                        </thead>
                        
                        <apex:repeat value="{!Quote.QuoteLineItems}" var="line" >
                      		<apex:outputPanel rendered="{!OR(rowNo=firstPageSize+1, MOD(rowNo-firstPageSize, nextPageSize)=1)}" style="page-break-before:always" layout="block" />
	                        
	                       	 <tbody id="lineItem">
	                            	<tr height="18">
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;"><font size="1" face="Arial"></font></td>
	                              		<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                                	<td valign="top" style="border-right:1px solid #000; padding:4px 3px;" align="right"><font size="1" face="Arial"></font></td>
	                            	</tr>
	                       	 </tbody>
	                         <tbody>
	                           
	                                <tr Style="text-align:center;">
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp;  {!ROUND(line.Id_uad__c,0)} </font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; <img src='{!line.URL__c}' style= "height:40px;width:40px;"/></font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Lead_Time__c}</font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Customization__c}</font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!line.Description} </font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!ROUND(line.Quantity,0)} </font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;">&nbsp; {!ROUND(line.UnitPrice,2)} </font></td>
	                                    <td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;"> &nbsp;  {!ROUND(line.Discount,0)}{!IF((line.Discount>0),'%',' ')} </font></td>
	                               		<td style="border-right:1px solid #000;"><font Style=" text-align:center;color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:10px;"> &nbsp;{!ROUND(line.TotalPrice,2)} </font></td>
	                               	</tr>  
	                        </tbody>
                        
                        	<apex:variable var="rowNo" value="{!rowNo+1}"/>
                        </apex:repeat>  
                      
	</table>

 

I spent to much time on it i started to mess my self a little à___à

 

Hengky IlawanHengky Ilawan
Hi Antony,

The apex:outputpanel generated as div, and div is not supposed to be a child object of table. It is invalid.

Regards,
Hengky
AntonyasLenAntonyasLen

but the line you showed to me

<apex:outputPanel rendered="{!OR(rowNo=firstPageSize+1, MOD(rowNo-firstPageSize, nextPageSize)=1)}" style="page-break-before:always" layout="block" />

 The output Panel is independant, so i should the same with div? It's kind a mess but thanks.

 

Regards,

Antony

Hengky IlawanHengky Ilawan

What I mean is:

 

Your generated HTML codes look something like this:

 

<table width="100%" border="0" cellspacing="0" height="350" cellpadding="0" style="border:1px solid #000;page-break-before:auto; ">
    <thead>
        <tr style="bgcolor:#e8e8e8;height:20;">
        ...
        </tr>
    </thead>

    <div id="j_id0:j_id ... style="page-break-before:always"></di>

    <tbody id="lineItem">
        <tr height="18">
        ...
        </tr>
    </tbody>
    <tbody id="lineItem">
        <tr Style="text-align:center;">
        ...
        </tr>
    </tbody>
...
...
</table>

 And a <div> inside a <table> is not valid.

 

Regards,

Hengky

AntonyasLenAntonyasLen

ok ok ....

So i have to restart my page with div? or apex:output?

Hengky IlawanHengky Ilawan

Yup. Use DIV instead.

 

Regards,

Hengky

AntonyasLenAntonyasLen

Thanks dude!

You spent a lot of time and it was very helpful.

 

The solution is to use DIV when we need to create a dynamic Tab.

 

 

Now i juste have to manage dynamically when my Salesman will create very HUGE Opportunity.

 

 

Here the final tab:

 

    <apex:repeat value="{!Quote.QuoteLineItems}" var="line" >
                      		<apex:outputPanel rendered="{!OR(rowNo=firstPageSize+1, MOD(rowNo-firstPageSize, nextPageSize)=1)}" style="page-break-before:always;border-top:1px solid #000;" layout="block" />
	                        
		<div style="width:100%; display:table;">
	        	<div style="display:table-row;text-align:center;">
					<div style="border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell; width:8% ">
						<font Style=" color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp;  {!ROUND(line.Id_uad__c,0)} </font>
					</div>
				   <div style="border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell;width:9%;vertical-align:middle;">
					 	<img src='{!line.URL__c}' style= "height:40px;width:40px;align:center"/>
				   </div>
				   <div style="border-left:1px solid #000;border-bottom:1px solid #000; display:table-cell;width:7%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp; {!line.Lead_Time__c}</font>
				   </div>
				   <div style="border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell;width:14%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp; {!line.Customization__c}</font>
					</div>
					<div style="border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell; width:17%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp; {!line.Description} </font>
					</div>
				   <div style="border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell;width:7%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp; {!ROUND(line.Quantity,0)} </font>
				   </div>
				   <div style="text-align:right;border-left:1px solid #000;border-bottom:1px solid #000;display:table-cell; width:10%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;">&nbsp; {!ROUND(line.UnitPrice,2)} </font>
				   </div>
				   <div style="border-left:1px solid #000;border-bottom:1px solid #000;  display:table-cell;width:6%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;"> &nbsp;  {!ROUND(line.Discount,0)}{!IF((line.Discount>0),'%',' ')} </font>
				   </div>
				   <div style="text-align:right;border-left:1px solid #000;border-bottom:1px solid #000;  display:table-cell;width:10%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;"> &nbsp;  {!ROUND(line.Discounted_unit_price__c,2)} </font>
				   </div>
				   <div style="text-align:right; border-left:1px solid #000;border-bottom:1px solid #000;border-right:1px solid #000;display:table-cell; width:12%">
						<font Style="color:#6e7277; face:Arial, Helvetica, sans-serif; font-size:9px;"> &nbsp;{!ROUND(line.TotalPrice,2)} </font>
				   </div>
       			 </div>
		</div>
	

                        
                        	<apex:variable var="rowNo" value="{!rowNo+1}"/>
                        </apex:repeat> 

 

Hengky IlawanHengky Ilawan

No problem, nice to see it finally works.

Anyway, it should be fine even if you have 30 or 40 line items. The page break will be inserted nicely at the point as defined in the apex:variable:

 

<apex:variable var="firstPageSize" value="{!5}"/>
<apex:variable var="nextPageSize" value="{!15}"/>

 

Regards,

Hengky

This was selected as the best answer
AntonyasLenAntonyasLen

Work until 30-40? awesome !