You need to sign in to do that
Don't have an account?
Splitting datatable in pdf onto separate pages
Hi,
My knowledge on coding is very basic so I am not sure it is possble to do what I'd like or if I have to find an alternate solution. Basically I am rendering a pdf which lists of of the delegates who have attended a training course and stating if they have passed or failed.
I am doing this in a pdf attachment to an email. I had it working fine until I found a course with 30+ delegates as the table just continues to render over the page footer and beyond. Is there anyway to easily split this table after 30 entries (I would like to avoid anything creating controllers etc as they are over my head)?
This is my code (the red section is the data table):
<messaging:attachment renderAs="pdf" filename="Exam results notification">
<html>
<head><style type="text/css" media="print">
body {color:#666666; font-family:"Arial Unicode MS"; font-size:11pt; font-style:normal; }
@page{
@bottom-left {
content: element(footer);
}
size: A4 portrait;
margin-top:0cm;
margin-left:0cm;
margin-right:0cm;
margin-bottom:0cm;
}
div.footer {
display: block;
position: running(footer);
line-height: 10pt;
font-size: 7.5pt;
color: #A9A9A9;
z-index:2;
}
</style>
</head>
<body>
<img src="{!URLFOR($Resource.Template)}" style="position: fixed; left: 0cm; top: 0cm; z-index:-2;" width="21cm" height="29.7"/>
<apex:dataTable cellpadding="2" width="15.92cm" border="0.2" style=" text-align:center; position: fixed; left: 2.54cm; top: 8cm; line-height: 12pt; font-size:11pt; z-index:+2;" columns="5" value="{!relatedTo.Enrollments__r}" var="cx" >
<apex:column width="3cm" >
<apex:facet name="header">Number</apex:facet>
{!cx.name}
</apex:column>
<apex:column >
<apex:facet name="header">姓名</apex:facet>
{!cx.delegate_name__r.LastNameLocal}{!cx.delegate_name__r.FirstNameLocal}
</apex:column>
<apex:column >
<apex:facet name="header">單位</apex:facet>
{!cx.delegate_name__r.department}
</apex:column>
<apex:column >
<apex:facet name="header">英文姓名</apex:facet>
{!cx.delegate_name__r.LastName}{!cx.delegate_name__r.FirstName}
</apex:column>
<apex:column width="2cm" >
<apex:facet name="header">Pass/Fail</apex:facet>
{!IF(OR(CONTAINS(cx.Exam_results__c,'Fail'),CONTAINS(cx.Exam_results__c,'fail')),'F','P')}
</apex:column>
</apex:dataTable>
<table width="15.92cm" valign="top" style="position: fixed; left: 2.54cm; top: 27.1cm; line-height: 10pt; font-size:7.5pt; color: #A9A9A9;" >
<colgroup>
<col span="4" width="3.98cm" />
</colgroup>
<tr valign="top">
<td>
address
</td>
<td>address</td>
<td></td>
<td></td>
</tr>
</table>
</body></html>
</messaging:attachment>
Many Thanks for any help you can offer.
Hi,
Just for information. I managed to achieve what I wanted using the following:
<messaging:attachment renderAs="pdf" filename="Exam results notification">
<html>
<head><style type="text/css" media="print">
body {color:#666666; font-family:"Arial Unicode MS"; font-size:11pt; font-style:normal;}
@page{
@bottom-left {
content: element(footer);
}
@top-right {
content: "Page " counter(page) " of " counter(pages);
font-family:"Arial Unicode MS";
font-size:11pt;
}
@top-left-corner {
content: element(header);
}
size: A4 portrait;
margin-top:5cm;
margin-left:2.54cm;
margin-right:2.54cm;
margin-bottom:5cm;
}
table {
-fs-table-paginate: paginate;
}
div.footer {
display: block;
padding: 10px;
position: running(footer);
line-height: 10px;
z-index: 3;
color: #A9A9A9;
font-family:"Arial Unicode MS";
font-size:7.5pt;
}
div.header {
display: block;
position: running(header);
}
</style>
</head>
<div class="header" >
<table table-layout="fixed">
<img src="{!URLFOR($Resource.Document_Logo)}" width="21cm" height="28.7"/>
</table>
</div>
<div class="footer" >
<table width="15.92cm" style="left: 2.54cm; top: 27.1cm; line-height: 10pt;" align="left" valign="top" table-layout="fixed">
<tr valign="top">
<td>
address
</td>
</tr>
</table>
</div>
<body>
<table cellpadding="3" cellspacing="0" styleclass="table" width="15cm" border="0.1" style="left: 2.54cm; text-align:center; font-size:11pt;">
<THEAD>
<tr>
<th style="border:1px solid #000000;border-right:0;">Number</th>
<th style="border:1px solid #000000;border-right:0;">姓名</th>
<th style="border:1px solid #000000;border-right:0;">單位</th>
<th style="border:1px solid #000000;border-right:0;">英文姓名</th>
<th style="border:1px solid #000000;">Pass/Fail</th>
</tr>
</THEAD>
<apex:repeat value="{!relatedTo.Enrollments__r}" var="cx">
<TBODY>
<tr>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.name}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.LastNameLocal}{!cx.delegate_name__r.FirstNameLocal}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.department}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.LastName}{!cx.delegate_name__r.FirstName}</td>
<td style="border:1px solid #000000;border-top:0;">{!IF(OR(CONTAINS(cx.Exam_results__c,'Fail'),CONTAINS(cx.Exam_results__c,'fail')),'F','P')}</td>
</tr>
</TBODY>
</apex:repeat>
</table>
</body>
</html>
</messaging:attachment>
Took a bit longer than I hoped but will be able to reuse this again in future!.
All Answers
You should use css media selectors related to using tbody and thead, something like this:
http://stackoverflow.com/questions/274149/css-repeat-table-headers-in-print-mode
Note that salesforce.com is using Flying Saucer for its PDF rendering.
Some other helpful notes:
http://stackoverflow.com/questions/10512324/css-to-pdf-the-css-in-flying-saucer-fs-table-paginate-result-in-border-collap
http://www.w3.org/TR/html4/struct/tables.html#edef-THEAD
Thanks so much sfdcfox,
I've moved forward a step in that I can get the table breaking over the pages and with the headers on each page by adding in:
table { -fs-table-paginate: paginate; }
to my style sheet and changing the datatable to:
<apex:dataTable cellpadding="2" styleclass="table" width="15.92cm" border="0.2" style="text-align:center; line-height: 12pt; font-size:11pt;" columns="5" value="{!relatedTo.Enrollments__r}" var="cx" >
I needed to remove the position: fixed part to make it work. However I now need to position the table nicely on the page. I tried position: relative but this stopped the headers appearing on each page.
Has anyone any further suggestions..... Many Thanks.
You'll probably need to use a padding or margin attribute. You can't have a table that's both positioned and running (at least, not in Flying Saucer, as far as I am aware).
Hi,
Just for information. I managed to achieve what I wanted using the following:
<messaging:attachment renderAs="pdf" filename="Exam results notification">
<html>
<head><style type="text/css" media="print">
body {color:#666666; font-family:"Arial Unicode MS"; font-size:11pt; font-style:normal;}
@page{
@bottom-left {
content: element(footer);
}
@top-right {
content: "Page " counter(page) " of " counter(pages);
font-family:"Arial Unicode MS";
font-size:11pt;
}
@top-left-corner {
content: element(header);
}
size: A4 portrait;
margin-top:5cm;
margin-left:2.54cm;
margin-right:2.54cm;
margin-bottom:5cm;
}
table {
-fs-table-paginate: paginate;
}
div.footer {
display: block;
padding: 10px;
position: running(footer);
line-height: 10px;
z-index: 3;
color: #A9A9A9;
font-family:"Arial Unicode MS";
font-size:7.5pt;
}
div.header {
display: block;
position: running(header);
}
</style>
</head>
<div class="header" >
<table table-layout="fixed">
<img src="{!URLFOR($Resource.Document_Logo)}" width="21cm" height="28.7"/>
</table>
</div>
<div class="footer" >
<table width="15.92cm" style="left: 2.54cm; top: 27.1cm; line-height: 10pt;" align="left" valign="top" table-layout="fixed">
<tr valign="top">
<td>
address
</td>
</tr>
</table>
</div>
<body>
<table cellpadding="3" cellspacing="0" styleclass="table" width="15cm" border="0.1" style="left: 2.54cm; text-align:center; font-size:11pt;">
<THEAD>
<tr>
<th style="border:1px solid #000000;border-right:0;">Number</th>
<th style="border:1px solid #000000;border-right:0;">姓名</th>
<th style="border:1px solid #000000;border-right:0;">單位</th>
<th style="border:1px solid #000000;border-right:0;">英文姓名</th>
<th style="border:1px solid #000000;">Pass/Fail</th>
</tr>
</THEAD>
<apex:repeat value="{!relatedTo.Enrollments__r}" var="cx">
<TBODY>
<tr>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.name}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.LastNameLocal}{!cx.delegate_name__r.FirstNameLocal}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.department}</td>
<td style="border:1px solid #000000;border-top:0;border-right:0;">{!cx.delegate_name__r.LastName}{!cx.delegate_name__r.FirstName}</td>
<td style="border:1px solid #000000;border-top:0;">{!IF(OR(CONTAINS(cx.Exam_results__c,'Fail'),CONTAINS(cx.Exam_results__c,'fail')),'F','P')}</td>
</tr>
</TBODY>
</apex:repeat>
</table>
</body>
</html>
</messaging:attachment>
Took a bit longer than I hoped but will be able to reuse this again in future!.
I have my rendered PDF with my header and footer showing, but I can't seem to get my pagination right, my footer gets on top of my content so it doesn't show.
Any ideas on what I can do?
Here's my code:
<apex:page controller="cnReportHoras" showHeader="false" standardStylesheets="false" renderAs="pdf">
<apex:stylesheet value="{!URLFOR($Resource.Estatico, 'css/Style.css')}"/>
<head>
<link href="https://fonts.googleapis.com/css?family=Comfortaa:300,400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,300" rel="stylesheet" type="text/css" />
<style>
@font-face {
font-family: 'Comfortaa';
font-style: normal;
font-weight: 300;
src: local('Comfortaa Light'), local('Comfortaa-Light'), url(https://themes.googleusercontent.com/static/fonts/comfortaa/v5/r_tUZNl0G8xCoOmp_JkSCnhCUOGz7vYGh680lGh-uXM.woff) format('woff');
}
table {
-fs-table-paginate: paginate;
}
table tr{
page-break-inside:avoid;
}
#footer_container {
bottom:0;
left:0;
position:fixed;
width:100%;
}
#footer {
margin:0 auto;
}
#header-cont {
width:100%;
position:fixed;
top:0px;
}
#header {
margin:0px auto;
}
@page{
@bottom-left {
content: element(footer);
}
@top-right {
content: "Page " counter(page) " of " counter(pages);
}
@top-left-corner {
content: element(header);
}
margin-top:2cm;
margin-left:1.54cm;
margin-right:1.54cm;
margin-bottom:2cm;
}
div.footer {
display: block;
padding: 5px;
position: running(footer);
}
.pagenumber:before {
content: counter(page);
}
.pagecount:before {
content: counter(pages);
}
</style>
</head>
<div id="header-cont">
<div id="header">
<img src="{!URLFOR($Resource.Estatico, 'img/s4gheader.png')}" width="100%"/>
</div>
</div>
<div class="clear" style="height:30px;" />
<body style="margin-top:200px; margin-bottom:60px; font-family: 'Comfortaa'">
<table width="100%" class="tablaGral" >
<tr>
<td width="70%">
<img src="{!URLFOR($Resource.Estatico, 'img/s4g-status.png')}" width="100%" />
</td>
<td width="30%">
<table class="tableC">
<tr>
<td>HORAS CONTRATADAS: </td>
<td>{!proyectos[0].horasEstimadas} hrs.</td>
</tr>
<tr>
<td style="vertical-align:middle;">CONSUMO: </td>
<td>
<apex:image id="activo" value="{!URLFOR($Resource.Estatico, 'img/render1.png')}" width="60" rendered="{!if(proyectos[0].percConsumido<100,true,false)}" />
<apex:image id="agotado" value="{!URLFOR($Resource.Estatico, 'img/render2.png')}" width="60" rendered="{!if(proyectos[0].percConsumido>=100,true,false)}" />
</td>
</tr>
<tr>
<td>TODAVIA QUEDAN: </td>
<td>{!proyectos[0].horasRestantes} hrs.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="20%">
<table width="85%">
<tr>
<th>Cliente </th>
<th>Fecha inicio</th>
<th>Fecha cierre</th>
</tr>
<tr>
<td>{!proyectos[0].cliente}</td>
<td style="color:red;">
<apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
<apex:param value="{!proyectos[0].comienzoPlanificado}" />
</apex:outputText>
</td>
<td style="color:red;">
<apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
<apex:param value="{!proyectos[0].finPlanificado}" />
</apex:outputText>
</td>
</tr>
</table>
</td>
<td width="80%">
</td>
</tr>
</table>
<div class="clear" style="height:50px;"/>
<div class="panel panel-vercasos" style="border: 1px solid; ">
<apex:pageBlock title="Peticiones">
<apex:pageBlockTable value="{!peticiones}" var="peticion" id="tablaPeticiones" styleClass="table" cellspacing="10" rowClasses="odd,even">
<apex:column >
<apex:facet name="header">Petición</apex:facet>
<apex:outputField value="{!peticion.Id_Peticion__c}"/>
</apex:column>
<apex:column >
<apex:facet name="header">Asunto</apex:facet>
<apex:outputField value="{!peticion.subject}"/>
</apex:column>
<apex:column >
<apex:facet name="header">Horas</apex:facet>
<center><apex:outputField value="{!peticion.Horas_estimadas_peticion__c}" /></center>
</apex:column>
<apex:column >
<apex:facet name="header"><center>Estado</center></apex:facet>
<apex:outputField value="{!peticion.Estado_Peticion__c}" />
</apex:column>
<apex:column >
<apex:facet name="header">Fecha Petición</apex:facet>
<center><apex:outputField value="{!peticion.Fecha_Estimada_Peticion__c}" /></center>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
<div class="clear" style="height:20px;" />
</div>
</body>
<div id="footer_container">
<div id="footer">
<img src="{!URLFOR($Resource.Estatico, 'img/s4gfooter.png')}" width="100%" height="100%" />
</div>
</div>
</apex:page>
THANK YOU!
thanks