How do we continue to print products on page 2 of an invoice?

We have to configure multi-page printing for a client. We are able to contain 19 products on a single page.

To continue printing on page 2, we need to continue printing the products in concisely the same y-axis as on page 1. For example, products must begin printing from exactly 400 pixels from the top on every page.

Please assist.

Is it a preprinted format? If so, you need to have the item list pagination within your itemlist printing routine. This way you can locate the printing block and commence balances between pages and print on the final page.

If you could precisely and concisely list the steps required to make that happen, it’d be great. :slight_smile:

That depends on your code. You need to estimate the number of items to be fitted on a single page and check accordingly. Carrying item numbers and balances will be an issue but can be easily handled through scripting knowledge. When you reach the last page, finish the format accordingly.
One issue is to provide exact positioning as the scripting used has some strange behavior changed by printers and need to be managed per printer type.

@Tufan_Kaynak2

This is the complete Sales Invoice format for our client. It is rookie since we’re new to this. How do we adjust for multi-page printing?

{% set company_links = frappe.get_all('Dynamic Link', filters={'link_doctype': 'Company', 'link_name': doc.company, 'parenttype': 'Address'}, fields=['parent']) %}
{% if company_links %}
{% set company_address_line1 = frappe.db.get_value("Address", company_links[0].parent, "address_line1") %}
{% set company_address_line2 = frappe.db.get_value("Address", company_links[0].parent, "address_line2") %}
{% set company_city = frappe.db.get_value("Address", company_links[0].parent, "city") %}
{% set company_country = frappe.db.get_value("Address", company_links[0].parent, "country") %}
{% set company_phone = frappe.db.get_value("Address", company_links[0].parent, "phone") %}
{% endif %}

{% set customer_address_links = frappe.get_all('Dynamic Link', filters={'link_doctype': 'Customer', 'link_name': doc.customer, 'parenttype': 'Address'}, fields=['parent']) %}
{% if customer_address_links %}
{% set customer_address_line1 = frappe.db.get_value("Address", customer_address_links[0].parent, "address_line1") %}
{% set customer_address_line2 = frappe.db.get_value("Address", customer_address_links[0].parent, "address_line2") %}
{% set customer_city = frappe.db.get_value("Address", customer_address_links[0].parent, "city") %}
{% set customer_country = frappe.db.get_value("Address", customer_address_links[0].parent, "country") %}
{% set customer_phone = frappe.db.get_value("Address", customer_address_links[0].parent, "phone") %}
{% endif %}
<table style="width:100%;">
    <tbody>
        <tr>
            <td>
                <div style="font-size:20pt;font-weight:bold;">{{ doc.company }}</div>
                {% if company_address_line1 or company_address_line2 %}{{ company_address_line1 }}<br>{{ company_address_line2 }}{% endif %}
                {% if company_city or company_country %}{{ company_city }}, {{ company_country }}{% endif %}<br>
                <span>
                    <strong>Contact: </strong>
                </span>
                <span style="margin-right:16px;">{{ company_phone }}</span>
                <span>
                    <strong>TRN: </strong>
                </span>
                <span>{{ frappe.db.get_value("Company", doc.company, "tax_id") }}</span>
            </td>
        </tr>
        <tr><td id="title" style="text-align:center;font-size:14pt;">{{ doc.select_print_heading or "Sales Invoice" }}</td></tr>
    </tbody>
</table>

<!-- Customer -->
<table id="customer" style="width:100%;">
    <tr>
        <td style="width:65%;">
            <table class="table table-bordered">
                <tbody>
                    <tr>
                    	<td class="text-left"><strong>Customer</strong></td>
                    	<td class="text-left" colspan="3" style="min-width:300px;">{{ doc.customer_name }}</td>
                	</tr>
                	<tr>
                        <td class="text-left"><strong>Address</strong></td>
                    	<td class="text-left" colspan="3" style="min-width:300px;">
                    	    {% if customer_address_line1 or customer_address_line2 or customer_city or customer_country %}
                        	    {% if customer_address_line1 %}
                        	    {{ customer_address_line1 }}
                        	    {% endif %}
                        	    {% if customer_address_line2 %}
                        	    , {{ customer_address_line2 }}
                        	    {% endif %}
                        	    {% if customer_city %}
                        	    , {{ customer_city }}
                        	    {% endif %}
                        	    {% if customer_country %}
                        	    , {{ customer_country }}
                        	    {% endif %}
                        	{% else %}
                        	    <br><br>
                        	{% endif %}
                	    </td>
                	</tr>
                	<tr>
                        <td class="text-left"><strong>TRN</strong></td>
                    	<td class="text-left" style="min-width:300px;">
                    	    {% set company_trn = frappe.db.get_value("Customer", doc.customer, "tax_id") %}
                    	    {% if company_trn %}
                    	        {{ company_trn }}
                	        {% endif %}
                	    </td>
                	</tr>
                </tbody>
        	</table>
        </td>
        <td style="width:35%;">
	        <table class="table table-bordered">
        	    <tbody>
        	        <tr>
                    	<td class="text-right"><strong>Date</strong></td>
                    	<td class="text-right">{{ doc.get_formatted("posting_date") }}</td>
        	        </tr>
        	        <tr>
                    	<td class="text-right"><strong>Invoice</strong></td>
                    	<td class="text-right">{{ doc.name }}</td>
        	        </tr>
        	        <tr>
                    	<td class="text-right"><strong>Due Date</strong></td>
                    	<td class="text-right">{{ doc.get_formatted("due_date") }}</td>
        	        </tr>
        	    </tbody>
            </table>
        </td>
    </tr>
</table>

<!-- Products -->
<table id="products" style="width:100%;min-height:550px;">
    <tbody>
        <tr>
            <td>
                <table class="table-bordered" style="width:100%;">
    <thead>
		<tr>
			<th>Sr</th>
			<th>Item Name</th>
			<th class="text-right">Pack Size</th>
			<th class="text-right">Qty</th>
			<th class="text-right">Rate</th>
			<th class="text-right">VAT</th>
			<th class="text-right">VAT Amt</th>
			<th class="text-right">Amt</th>
		</tr>
    </thead>
	<tbody>
		{%- for row in doc.items -%}
		<tr>
			<td style="width: 1%;">{{ row.idx }}</td>
			<td>
				{{ row.item_name }}
			</td>
			<td style="width: 13%; text-align: right;">
			    {{ row.qty }} x {{ row.stock_qty|int }} {{ row.stock_uom }}
		    </td>
			<td style="width: 10%; text-align: right;">
			    {{ row.uom or row.stock_uom }} {{ row.qty }}
		    </td>
			<td style="width: 9%; text-align: right;">
			    {{ row.rate }}
		    </td>
			<td style="width: 7%; text-align: right;">
			    {{ row.tax_rate }}%
		    </td>
			<td style="width: 10%; text-align: right;">
			    {{ row.tax_amount }}
		    </td>
			<td style="width: 10%; text-align: right;">
			    {{ row.amount }}
		    </td>
		</tr>
		{%- endfor -%}
	</tbody>
</table>
            </td>
        </tr>
    </tbody>
</table>

<!-- Total -->
<table id="summary" style="width:100%;">
    <tr>
        <td style="width:70%;">
            <table class="table table-bordered">
                <tbody>
                    <tr>
                        <td><strong>Total Qty</strong></td><td>{{ doc.get_formatted("total_qty") }}</td>
                    </tr>
                    <tr>
                        <td><strong>In words</strong></td><td>{{ doc.get_formatted("in_words") }}</td>
                    </tr>
                </tbody>
            </table>
        </td>
        <td style="width:30%;">
            <table class="table table-bordered">
                <tbody>
                    <tr>
                        <td><strong>Total</strong></td><td>{{ doc.get_formatted("total") }}</td>
                    </tr>
                    <tr>
                        <td><strong>Tax</strong></td><td>{{ doc.get_formatted("total_taxes_and_charges") }}</td>
                    </tr>
                    <tr>
                        <td><strong>Discount</strong></td><td>{{ doc.get_formatted("discount_amount") }}</td>
                    </tr>
                    <tr>
                        <td><strong>Grand Total</strong></td><td>{{ doc.get_formatted("grand_total") }}</td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
</table>

<!-- Terms -->
{% if not no_letterhead and footer %}
<div class="letter-head-footer">
    {{ footer }}
</div>
{% endif %}

.print-format th {
    background-color: transparent !important;
}
#title {
    padding: 0 !important;
}
table table {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}
#customer > tbody > tr > td:first-child,
#summary > tbody > tr > td:first-child {
    padding-left: 0 !important;
}
#customer > tbody > tr > td:last-child,
#summary > tbody > tr > td:last-child {
    padding-right: 0 !important;
}
#products > tbody > tr > td:first-child {
    padding-left: 0 !important;
}
#products > tbody > tr > td:last-child {
    padding-right: 0 !important;
}

Note: We have an estimate of 19 single row items per page.