There are already articles out there that document this but I use this more and more and would rather just find it on my site than going through multiple bookmarks.
Why?
This use-case is for a customer who simply wanted a quote template to be rendered for PDF or print format. I have another article for a different client who wants a pretty advanced HTML template (well it's a HTML table with rowspans and the borders need to merge cells). But here we're simply going to use ZohoCreator and its PDF rendering options.
What's wrong with just using CSS? It looks beautiful on ZohoCreator pages but then you hit the PDF button and it pretty much vomits your output back to the 90s. The code snippet below is just for a standard template with a modern design.
How?
Ok, admittedly, when first designing the template, there could have been a fair few improvements right out of the gate. Then the client comes back and says things like "can we add this?", "can it say this instead?", "can it be in a bigger font?"... without pushing back too much, it can end up looking like those old websites with HTML tables. We're going to use a HTML table again but that's because I want to send it to the PDF renderer in ZohoCreator and want all the data to stay aligned. Using only DIV layers can cause a few unexpected layouts in ZohoCreator.
The Quick Answer: the page margins
Tackling the page margin on render, I wrap the whole lot inside a DIV layer with the key attribute zcpage-spacing:
<div id="my-container" zcpage-spacing="40"> <div id="my-header" zcpage-headerhtml="true"> ... </div> <div id="my-body"> ... </div> <div id="my-footer" zcpage-footerhtml="true"> ... </div> </div>
- <div id="my-container" zcpage-spacing="40">
- <div id="my-header" zcpage-headerhtml="true">
- ...
- </div>
- <div id="my-body">
- ...
- </div>
- <div id="my-footer" zcpage-footerhtml="true">
- ...
- </div>
- </div>
The Quick Answer: the header
This repeats the header on every page. The key here is the HTML attribute zcpage-headerhtml:
<div id="my-header" zcpage-headerhtml="true">
<table class="my-table">
<tbody>
<tr>
<td><img src="/<%=v_LogoPhotoUrl%>" width="150" height="auto" alt="My Company" /></td>
<td>My Company Ltd<br />Test Street,<br />Test County TEST1 ZIP1<br /><br />+44 (0)1234 567890<br />This email address is being protected from spambots. You need JavaScript enabled to view it.</td>
<td>QUOTE</td>
</tr>
</tbody>
</table>
<hr />
<br />
</div>
- <div id="my-header" zcpage-headerhtml="true">
- <table class="my-table">
- <tbody>
- <tr>
- <td><img src="<%=v_LogoPhotoUrl%>" width="150" height="auto" alt="My Company" /></td>
- <td>My Company Ltd<br />Test Street,<br />Test County TEST1 ZIP1<br /><br />+44 (0)1234 567890<br />This email address is being protected from spambots. You need JavaScript enabled to view it.</td>
- <td>QUOTE</td>
- </tr>
- </tbody>
- </table>
- <hr />
- <br />
- </div>
The Quick Answer: the footer
This repeats the footer on every page. The key point is the HTML attribute zcpage-footerhtml; but note the 3 other CSS classes zcpage-pagenumber, currentPageNumber, and totalPageNumber which will output the current page number and total count of pages respectively:
<div id="my-footer" zcpage-footerhtml="true" class="align-center"> <hr /> <br /> <div class="zcpage-pagenumber"> Page <span class="currentPageNumber"> </span> of <span class="totalPageNumber"> </span><br /> </div> <div class="footer-copyright"> Copyright © <%=v_ThisYear%> My Company Ltd. All Rights Reserved. </div> </div>
- <div id="my-footer" zcpage-footerhtml="true" class="align-center">
- <hr />
- <br />
- <div class="zcpage-pagenumber">
- Page <span class="currentPageNumber"> </span> of <span class="totalPageNumber"> </span><br />
- </div>
- <div class="footer-copyright">
- Copyright © <%=v_ThisYear%> My Company Ltd. All Rights Reserved.
- </div>
- </div>
In for a penny, in for a pound
Here's my full template deluge/html/css code to put in a Zoho Creator page excluding the content (edited for Public display - Not the used final version):
<%{ /* ******************************************************************************* Function: - Label: Zoho Creator Page: Print_Quote Trigger: This is the HTML snippet for the "Print Quote" page Purpose: The below code is the HTML combined with Deluge to output a quote in this template. Inputs: p_Quotes [collection of the quote form - when tick multiple records in a list] Outputs: A HTML page that can be rendered in PDF or Print Date Created: 2023-04-03 (Joel Lipman) - Initial release Date Modified: ??? - ??? More Information: https://help.zoho.com/portal/en/kb/creator/developer-guide/others/url-patterns/articles/functionality-based-urls#To_convert_Page_to_PDF https://help.zoho.com/portal/en/kb/creator/developer-guide/pages/create-and-manage-pages/articles/guidelines-for-exporting-page-into-pdf#31_PDF_Margin ******************************************************************************* */ // // the publish key of the product images report v_ProductPhoto_PublishKey = "AAAAABBBBBCCCCDDDDEEEFFFGGGGHHHIIIJJJKKLLLMMMNNOOOPPPQQWRRRSSTTUUVVWWXXYYZZ122345567890"; // my company logo (must be a public URL to render in the PDF) v_LogoPhotoUrl = "https://mycompany.com/assets/img/template_logo.png"; // getting current year v_ThisYear = zoho.currentdate.getYear(); // converting the submitted quote record IDs as a list l_QuoteIDs = ifnull(input.p_Quotes,"").toList(); // // get customer information v_CurrencyHtmlEntity = "£"; v_Firstname = ""; v_Lastname = ""; v_Email = ""; v_QuoteDate = zoho.currentdate.toString("dd-MMM-yyyy"); v_AddedBy = "The No. 1 Salesperson"; for each v_QuoteID in l_QuoteIDs { c_Quote = Quote[ID == v_QuoteID]; if(c_Quote.count() > 0) { if(c_Quote.Name != null) { v_Firstname = c_Quote.Name.first_name; v_Lastname = c_Quote.Name.last_name; } if(c_Quote.Email != null) { v_Email = c_Quote.Email; } v_QuoteDate = c_Quote.Modified_Time.toString("dd-MMM-yyyy"); c_AddedBy = Staff[Zoho_Creator_User == zoho.loginuser]; if(c_AddedBy.count() > 0) { v_AddedBy = c_AddedBy.Name; } break; } } %> <style> /* page sizing */ @page { size: A4; margin: 0; } /* CSS for when opting to print rather than render in PDF */ /* Overridden by zcpage-pagenumber which hides the entire div when printing */ .currentPageNumber { content: "1"; } .totalPageNumber { content: "1"; } /* globals */ #my-header td, #my-container th, #my-container td, #my-footer{ color: #111; font-family: 'Lato', sans-serif !important; font-size: 10pt; font-weight:300; } .my-table{ width: 100%; margin-bottom:20px; } .my-table td, .my-table th { padding: 5px 10px; } /* letterhead header */ #my-header .my-table thead{ margin-bottom:30px; } #my-header .my-table tr td:first-child{ width: 175px; } #my-header .my-table tr td:nth-child(2){ font-size: 7pt; text-transform: uppercase; } #my-header .my-table tr td:nth-child(3){ text-transform: uppercase; font-size: 36pt; font-weight: 100; color: #777; text-align: right; vertical-align: top; } /* main content */ #my-content table:first-child td{ vertical-align:top; } #my-content table:first-child label{ text-transform: uppercase; color: #777; display:inline-block; width:100px; } #my-content table:first-child span{ font-weight:400; display:inline-block; min-width:100px; } #my-content table:first-child tr td:nth-child(2){ width: 240px; } /* line items */ #my-line-items thead tr th{ color: #777; text-align:right; text-transform: uppercase; vertical-align: bottom; border-bottom: 1px solid #eee; } #my-line-items thead tr th:first-child{ width: 50%; text-align:left; } #my-line-items tbody tr td img{ width: 75px; height: auto; max-height: 75px; max-width: 75px; margin-right: 15px; float:left; } #my-line-items tbody tr td{ font-weight:400; text-align:right; vertical-align:top; padding: 0 10px 10px 10px; } #my-line-items tbody tr td span{ font-size: 8pt; } #my-line-items tbody tr td span:first-child{ font-size: 10pt; } #my-line-items tbody tr td:first-child{ text-align:left; } #my-line-items tbody tr td:first-child div{ float:left; display:inline-block; } #my-line-items tfoot tr th{ color: #777; text-align:right; text-transform: uppercase; vertical-align: bottom; } #my-line-items tfoot tr:nth-child(2) th{ color: #111; font-weight:400; border-top: 1px solid #eee; } /* customer notes */ #my-content table:nth-child(3) p{ font-size:7pt; } /* page footer */ #my-footer{ text-align:center; font-size:7pt; text-transform: uppercase; } #my-container hr{ border: 0; height: 1px; background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0)); } </style> <div id="my-container" zcpage-spacing="40"> <div id="my-header" zcpage-headerhtml="true"> <table class="my-table"> <tbody> <tr> <td><img src="/<%=v_LogoPhotoUrl%>" width="150" height="auto" alt="My Company" /></td> <td>My Company Ltd<br />Test Street,<br />Test County TEST1 ZIP1<br /><br />+44 (0)1234 567890<br />info@mycompany.com<br />www.mycompany.com<br /> <td>QUOTE</td> </tr> </tbody> </table> <hr /> <br /> </div> <div id="my-content"> <table class="my-table"> <thead> <tr> <td> <label>Quote For:</label><br /> <span><%=v_Firstname%> <%=v_Lastname%></span><br /> <span><%=v_Email%></span> </td> <td> <label>Quote Date:</label> <span><%=v_QuoteDate%></span><br /> <label>Quote By:</label> <span><%=v_AddedBy%></span><br /> </td> </tr> </thead> </table> <table class="my-table" id="my-line-items"> <thead> <tr> <th>Item Description</th> <th>Quantity</th> <th>Unit Price</th> <th>Unit Discount</th> </tr> </thead> <tbody> <% v_TotalQuantity = 0; v_TotalPrice = 0.00; v_TotalDiscount = 0.00; v_TotalAmount = 0.00; for each v_QuoteID in l_QuoteIDs { c_Quote = Quote[ID == v_QuoteID]; if(c_Quote.count() > 0) { v_LineItemTotal = 0.00; v_ThisQuantity = ifnull(c_Quote.Quantity,1).toLong(); v_TotalQuantity = v_TotalQuantity + v_ThisQuantity; // v_PriceDisplay = if(c_Quote.Unit_Price && c_Quote.Unit_Price > 0,v_CurrencyHtmlEntity + c_Quote.Unit_Price.round(2),"-"); v_PriceValue = if(c_Quote.Unit_Price && c_Quote.Unit_Price > 0,c_Quote.Unit_Price,0); v_PriceTotal = v_PriceValue * v_ThisQuantity; v_TotalPrice = (v_TotalPrice + v_PriceTotal).round(2); // v_DiscountDisplay = if(c_Quote.Discount_Amount && c_Quote.Discount_Amount > 0,v_CurrencyHtmlEntity + c_Quote.Discount_Amount.round(2),"-"); v_DiscountValue = if(c_Quote.Discount_Amount && c_Quote.Discount_Amount > 0,c_Quote.Discount_Amount,0); v_DiscountTotal = v_DiscountValue * v_ThisQuantity; v_TotalDiscount = (v_TotalDiscount + v_DiscountTotal).round(2); // v_LineItemTotal = (v_PriceTotal - v_DiscountTotal).round(2); v_TotalAmount = (v_TotalAmount + v_LineItemTotal).round(2); // // // product photo c_Product = Products[ID == c_Quote.Product]; if(c_Product.count() > 0) { v_ProductPhotoFile = c_Model.Product.getSuffix("http").getPrefix("\"").getSuffix("/image/"); v_ProductPhotoURL = "https://creatorexport.zoho.com/file" + zoho.appuri + "Products/" + c_Product.ID + "/Photo/image-download/" + v_ProductPhoto_PublishKey + "?filepath=" + v_ProductPhotoFile; } v_ItemImgDisp = "<img src='" + v_ProductPhotoURL + "' alt='" + c_Quote.Product.Product_Name + "' />"; // // item and description v_ItemDescDisp = "<span>" + c_Quote.Product.Product_Name + "</span><br />"; if(c_Quote.Special_Edition.containsIgnoreCase("yes")) { v_ItemDescDisp = "<span>SPECIAL EDITION</span><br />"; } // // other properties to add to the description v_ItemDescDisp = v_ItemDescDisp + "<span>Awesome Reason To Buy This #1</span><br />"; v_ItemDescDisp = v_ItemDescDisp + "<span>Awesome Reason To Buy This #2</span><br />"; // // condition grade v_ConditionChar = ifnull(c_Quote.Grade_Condition,"C").subString(0,1); v_ConditionDisp = if(v_ConditionChar == "N","New",v_ConditionChar + " Grade"); v_ItemDescDisp = v_ItemDescDisp + "<span>" + v_ConditionDisp + "</span><br />"; // // unique item reference if(c_Quote.Quote_Reference.contains("Q-")) { v_ItemDescDisp = v_ItemDescDisp + "<span><i>Ref. " + c_Quote.Quote_Reference + "</i></span><br />"; } %> <tr> <td><%=v_ItemImgDisp%><div><%=v_ItemDescDisp%></div></td> <td><%=v_ThisQuantity%></td> <td><%=v_PriceDisplay%></td> <td><%=v_DiscountDisplay%></td> <td><%=v_CurrencyHtmlEntity><%=v_LineItemTotal%></td> </tr> <% } } %> </tbody> <tfoot> <tr> <th></th> <th>Total Quantity</th> <th>Total Price</th> <th>Total Discount</th> <th>Total Amount</th> </tr> <tr> <th></th> <th><%=v_TotalQuantity%></th> <th><%=v_CurrencyHtmlEntity><%=v_TotalPrice%></th> <th><%=v_CurrencyHtmlEntity><%=v_TotalDiscount%></th> <th><%=v_CurrencyHtmlEntity><%=v_TotalAmount%></th> </tr> </tfoot> </table> <table class="my-table"> <tbody> <tr> <td colspan="4"> <p> Please note the following: I've put some really small print here just so that you don't really read this and appreciate that we have terms and conditions like every other business. </p> </td> </tr> </tbody> </table> </div> <div id="my-footer" zcpage-footerhtml="true" class="align-center"> <hr /> <br /> <div class="zcpage-pagenumber"> Page <span class="currentPageNumber"> </span> of <span class="totalPageNumber"> </span><br /> </div> <div class="footer-copyright"> Copyright © <%=v_ThisYear%> My Company Ltd. All Rights Reserved. </div> </div> </div> <% }%>
- <%{
- /* *******************************************************************************
- Function: -
- Label: Zoho Creator Page: Print_Quote
- Trigger: This is the HTML snippet for the "Print Quote" page
- Purpose: The below code is the HTML combined with Deluge to output a quote in this template.
- Inputs: p_Quotes [collection of the quote form - when tick multiple records in a list]
- Outputs: A HTML page that can be rendered in PDF or Print
- Date Created: 2023-04-03 (Joel Lipman)
- - Initial release
- Date Modified: ???
- - ???
- More Information:
- https://help.zoho.com/portal/en/kb/creator/developer-guide/others/url-patterns/articles/functionality-based-urls#To_convert_Page_to_PDF
- https://help.zoho.com/portal/en/kb/creator/developer-guide/pages/create-and-manage-pages/articles/guidelines-for-exporting-page-into-pdf#31_PDF_Margin
- ******************************************************************************* */
- //
- // the publish key of the product images report
- v_ProductPhoto_PublishKey = "AAAAABBBBBCCCCDDDDEEEFFFGGGGHHHIIIJJJKKLLLMMMNNOOOPPPQQWRRRSSTTUUVVWWXXYYZZ122345567890";
- // my company logo (must be a public URL to render in the PDF)
- v_LogoPhotoUrl = "https://mycompany.com/assets/img/template_logo.png";
- // getting current year
- v_ThisYear = zoho.currentdate.getYear();
- // converting the submitted quote record IDs as a list
- l_QuoteIDs = ifnull(input.p_Quotes,"").toList();
- //
- // get customer information
- v_CurrencyHtmlEntity = "£";
- v_Firstname = "";
- v_Lastname = "";
- v_Email = "";
- v_QuoteDate = zoho.currentdate.toString("dd-MMM-yyyy");
- v_AddedBy = "The No. 1 Salesperson";
- for each v_QuoteID in l_QuoteIDs
- {
- c_Quote = Quote[ID == v_QuoteID];
- if(c_Quote.count() > 0)
- {
- if(c_Quote.Name != null)
- {
- v_Firstname = c_Quote.Name.first_name;
- v_Lastname = c_Quote.Name.last_name;
- }
- if(c_Quote.Email != null)
- {
- v_Email = c_Quote.Email;
- }
- v_QuoteDate = c_Quote.Modified_Time.toString("dd-MMM-yyyy");
- c_AddedBy = Staff[Zoho_Creator_User == zoho.loginuser];
- if(c_AddedBy.count() > 0)
- {
- v_AddedBy = c_AddedBy.Name;
- }
- break;
- }
- }
- %>
- <style>
- /* page sizing */
- @page {
- size: A4;
- margin: 0;
- }
- /* CSS for when opting to print rather than render in PDF */
- /* Overridden by zcpage-pagenumber which hides the entire div when printing */
- .currentPageNumber {
- content: "1";
- }
- .totalPageNumber {
- content: "1";
- }
- /* globals */
- #my-header td,
- #my-container th,
- #my-container td,
- #my-footer{
- color: #111;
- font-family: 'Lato', sans-serif !important;
- font-size: 10pt;
- font-weight:300;
- }
- .my-table{
- width: 100%;
- margin-bottom:20px;
- }
- .my-table td,
- .my-table th {
- padding: 5px 10px;
- }
- /* letterhead header */
- #my-header .my-table thead{
- margin-bottom:30px;
- }
- #my-header .my-table tr td:first-child{
- width: 175px;
- }
- #my-header .my-table tr td:nth-child(2){
- font-size: 7pt;
- text-transform: uppercase;
- }
- #my-header .my-table tr td:nth-child(3){
- text-transform: uppercase;
- font-size: 36pt;
- font-weight: 100;
- color: #777;
- text-align: right;
- vertical-align: top;
- }
- /* main content */
- #my-content table:first-child td{
- vertical-align:top;
- }
- #my-content table:first-child label{
- text-transform: uppercase;
- color: #777;
- display:inline-block;
- width:100px;
- }
- #my-content table:first-child span{
- font-weight:400;
- display:inline-block;
- min-width:100px;
- }
- #my-content table:first-child tr td:nth-child(2){
- width: 240px;
- }
- /* line items */
- #my-line-items thead tr th{
- color: #777;
- text-align:right;
- text-transform: uppercase;
- vertical-align: bottom;
- border-bottom: 1px solid #eee;
- }
- #my-line-items thead tr th:first-child{
- width: 50%;
- text-align:left;
- }
- #my-line-items tbody tr td img{
- width: 75px;
- height: auto;
- max-height: 75px;
- max-width: 75px;
- margin-right: 15px;
- float:left;
- }
- #my-line-items tbody tr td{
- font-weight:400;
- text-align:right;
- vertical-align:top;
- padding: 0 10px 10px 10px;
- }
- #my-line-items tbody tr td span{
- font-size: 8pt;
- }
- #my-line-items tbody tr td span:first-child{
- font-size: 10pt;
- }
- #my-line-items tbody tr td:first-child{
- text-align:left;
- }
- #my-line-items tbody tr td:first-child div{
- float:left;
- display:inline-block;
- }
- #my-line-items tfoot tr th{
- color: #777;
- text-align:right;
- text-transform: uppercase;
- vertical-align: bottom;
- }
- #my-line-items tfoot tr:nth-child(2) th{
- color: #111;
- font-weight:400;
- border-top: 1px solid #eee;
- }
- /* customer notes */
- #my-content table:nth-child(3) p{
- font-size:7pt;
- }
- /* page footer */
- #my-footer{
- text-align:center;
- font-size:7pt;
- text-transform: uppercase;
- }
- #my-container hr{
- border: 0;
- height: 1px;
- background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
- }
- </style>
- <div id="my-container" zcpage-spacing="40">
- <div id="my-header" zcpage-headerhtml="true">
- <table class="my-table">
- <tbody>
- <tr>
- <td><img src="<%=v_LogoPhotoUrl%>" width="150" height="auto" alt="My Company" /></td>
- <td>My Company Ltd<br />Test Street,<br />Test County TEST1 ZIP1<br /><br />+44 (0)1234 567890<br />This email address is being protected from spambots. You need JavaScript enabled to view it.<br />www.mycompany.com<br />
- <td>QUOTE</td>
- </tr>
- </tbody>
- </table>
- <hr />
- <br />
- </div>
- <div id="my-content">
- <table class="my-table">
- <thead>
- <tr>
- <td>
- <label>Quote For:</label><br />
- <span><%=v_Firstname%> <%=v_Lastname%></span><br />
- <span><%=v_Email%></span>
- </td>
- <td>
- <label>Quote Date:</label> <span><%=v_QuoteDate%></span><br />
- <label>Quote By:</label> <span><%=v_AddedBy%></span><br />
- </td>
- </tr>
- </thead>
- </table>
- <table class="my-table" id="my-line-items">
- <thead>
- <tr>
- <th>Item Description</th>
- <th>Quantity</th>
- <th>Unit Price</th>
- <th>Unit Discount</th>
- </tr>
- </thead>
- <tbody>
- <%
- v_TotalQuantity = 0;
- v_TotalPrice = 0.00;
- v_TotalDiscount = 0.00;
- v_TotalAmount = 0.00;
- for each v_QuoteID in l_QuoteIDs
- {
- c_Quote = Quote[ID == v_QuoteID];
- if(c_Quote.count() > 0)
- {
- v_LineItemTotal = 0.00;
- v_ThisQuantity = ifnull(c_Quote.Quantity,1).toLong();
- v_TotalQuantity = v_TotalQuantity + v_ThisQuantity;
- //
- v_PriceDisplay = if(c_Quote.Unit_Price && c_Quote.Unit_Price > 0,v_CurrencyHtmlEntity + c_Quote.Unit_Price.round(2),"-");
- v_PriceValue = if(c_Quote.Unit_Price && c_Quote.Unit_Price > 0,c_Quote.Unit_Price,0);
- v_PriceTotal = v_PriceValue * v_ThisQuantity;
- v_TotalPrice = (v_TotalPrice + v_PriceTotal).round(2);
- //
- v_DiscountDisplay = if(c_Quote.Discount_Amount && c_Quote.Discount_Amount > 0,v_CurrencyHtmlEntity + c_Quote.Discount_Amount.round(2),"-");
- v_DiscountValue = if(c_Quote.Discount_Amount && c_Quote.Discount_Amount > 0,c_Quote.Discount_Amount,0);
- v_DiscountTotal = v_DiscountValue * v_ThisQuantity;
- v_TotalDiscount = (v_TotalDiscount + v_DiscountTotal).round(2);
- //
- v_LineItemTotal = (v_PriceTotal - v_DiscountTotal).round(2);
- v_TotalAmount = (v_TotalAmount + v_LineItemTotal).round(2);
- //
- //
- // product photo
- c_Product = Products[ID == c_Quote.Product];
- if(c_Product.count() > 0)
- {
- v_ProductPhotoFile = c_Model.Product.getSuffix("http").getPrefix("\"").getSuffix("/image/");
- v_ProductPhotoURL = "https://creatorexport.zoho.com/file" + zoho.appuri + "Products/" + c_Product.ID + "/Photo/image-download/" + v_ProductPhoto_PublishKey + "?filepath=" + v_ProductPhotoFile;
- }
- v_ItemImgDisp = "<img src='" + v_ProductPhotoURL + "' alt='" + c_Quote.Product.Product_Name + "' />";
- //
- // item and description
- v_ItemDescDisp = "<span>" + c_Quote.Product.Product_Name + "</span><br />";
- if(c_Quote.Special_Edition.containsIgnoreCase("yes"))
- {
- v_ItemDescDisp = "<span>SPECIAL EDITION</span><br />";
- }
- //
- // other properties to add to the description
- v_ItemDescDisp = v_ItemDescDisp + "<span>Awesome Reason To Buy This #1</span><br />";
- v_ItemDescDisp = v_ItemDescDisp + "<span>Awesome Reason To Buy This #2</span><br />";
- //
- // condition grade
- v_ConditionChar = ifnull(c_Quote.Grade_Condition,"C").subString(0,1);
- v_ConditionDisp = if(v_ConditionChar == "N","New",v_ConditionChar + " Grade");
- v_ItemDescDisp = v_ItemDescDisp + "<span>" + v_ConditionDisp + "</span><br />";
- //
- // unique item reference
- if(c_Quote.Quote_Reference.contains("Q-"))
- {
- v_ItemDescDisp = v_ItemDescDisp + "<span><i>Ref. " + c_Quote.Quote_Reference + "</i></span><br />";
- }
- %>
- <tr>
- <td><%=v_ItemImgDisp%><div><%=v_ItemDescDisp%></div></td>
- <td><%=v_ThisQuantity%></td>
- <td><%=v_PriceDisplay%></td>
- <td><%=v_DiscountDisplay%></td>
- <td><%=v_CurrencyHtmlEntity><%=v_LineItemTotal%></td>
- </tr>
- <%
- }
- }
- %>
- </tbody>
- <tfoot>
- <tr>
- <th></th>
- <th>Total Quantity</th>
- <th>Total Price</th>
- <th>Total Discount</th>
- <th>Total Amount</th>
- </tr>
- <tr>
- <th></th>
- <th><%=v_TotalQuantity%></th>
- <th><%=v_CurrencyHtmlEntity><%=v_TotalPrice%></th>
- <th><%=v_CurrencyHtmlEntity><%=v_TotalDiscount%></th>
- <th><%=v_CurrencyHtmlEntity><%=v_TotalAmount%></th>
- </tr>
- </tfoot>
- </table>
- <table class="my-table">
- <tbody>
- <tr>
- <td colspan="4">
- <p>
- Please note the following: I've put some really small print here just so that you don't really read this and appreciate that we have terms and conditions like every other business.
- </p>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="my-footer" zcpage-footerhtml="true" class="align-center">
- <hr />
- <br />
- <div class="zcpage-pagenumber">
- Page <span class="currentPageNumber"> </span> of <span class="totalPageNumber"> </span><br />
- </div>
- <div class="footer-copyright">
- Copyright © <%=v_ThisYear%> My Company Ltd. All Rights Reserved.
- </div>
- </div>
- </div>
- <%
- }%>
Additional Notes to Self:
- Some customers will want a column for VAT/Tax (Display amount and then percentage beneath in smaller)
- Line Item Totals have been added to the above code retrospectively without proper testing.
- Aggregate of total amount may be unnecessary as this could be the same under price total.
- Where a price is applied, values should be retained in decimal format with currency symbol prefixed if value is greater than zero.
Source(s):
- To convert Page to PDF - Used more for links to open the PDF renderer in a new tab.
- Zoho Creator - Developer Guide - Customize Layout of Exported Page