[Print Format Issue] Items Table not Continuing Properly on Next Page with Custom Letterhead

ERPNext Version: v15.46.2 (version-15)
Frappe Framework Version: v15.50.1 (version-15)

Issue:

I created a Custom Print Format for Sales Order and added a Letterhead.

However, I am facing an issue with the items table:

  • When an item has a very long description, the row breaks badly across pages.
  • Sometimes text is hidden or overlaps awkwardly between pages.
  • The row structure is not preserved when page breaks happen.
  • Even though the page breaks, the lines for the table rows do not continue correctly.

I have attached a sample PDF output showing the issue.

What I have already tried:

  • Adding page-break-inside: avoid; on <tr> and <td>.
  • Setting white-space: normal; word-break: break-word; for description columns.
  • Playing with table-layout: fixed and width styles.
  • Using Frappe’s standard print format classes like .print-format and .print-heading.
  • Adjusting the Letterhead margins and page sizes.

Still, the issue persists.

Screenshots


My Setup:

  • Custom Print Format (HTML Based)
  • Standard Letterhead (HTML Based)

Help Needed:

  • How can i add some space around header and footer?
  • How can I ensure table rows do not break badly across pages?
  • How can I preserve the table structure even if descriptions are long?
  • Should I adjust styles differently or is there a best practice for long text in tables in ERPNext v15?
  • Is there any known fix or recommended CSS for custom print formats with long tables and letterheads?

Custom Print Format code

{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}
	{% if letter_head and not no_letterhead %}
		<div class="letter-head">{{ letter_head }}</div>
	{% endif %}
	{% if print_heading_template %}
		{{ frappe.render_template(print_heading_template, {"doc":doc}) }}
	{% else %}
	{% endif %}
	{%- if doc.meta.is_submittable and doc.docstatus==2-%}
	<div class="text-center" document-status="cancelled">
		<h4 style="margin: 0px;">{{ _("CANCELLED") }}</h4>
	</div>
	{%- endif -%}
{%- endmacro -%}


{% for page in layout %}
<div class="page-break">
	<div {% if print_settings.repeat_header_footer and loop.index == 0 %} id="header-html" class="hidden-pdf" {% endif %}>
		{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}
	</div>
    <!--  Footer Start-->
      {% if print_settings %}
        <div id="footer-html" class="visible-pdf">
            {% if not no_letterhead and footer %}
            <div class="letter-head-footer">
                {{ footer }}
            </div>
            {% endif %}
            <p class="text-center small page-number visible-pdf">
                {{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
            </p>
        </div>
      {% endif %}
    <!--  Footer End -->

    <div class="section-break">
        <!-- Document Title -->
        <h2 class="document-title text-center">{{ doc.doctype|upper }}</h2>

        <!-- Document Information -->
        <table style="width: 100%; font-size: 10pt; margin-top: 10px;">
          <tr class="table-row">
            <td style="width: 33%; vertical-align: top;">
              <strong>Customer:</strong><br>
              {{ doc.customer_name or doc.party_name }}<br>
            </td>
            <td style="width: 33%; vertical-align: top;">
              <strong>Shipping Address:</strong><br>
            </td>
            <td style="width: 33%; vertical-align: top;">
              <strong>Order No:</strong> {{ doc.name }}<br>
            </td>
          </tr>
        </table>


        <!-- CUSTOMER NOTE -->
        <div style="margin-top: 10px; font-size: 10pt;">
          <p>Dear {{ doc.customer_name if doc.doctype != 'Quotation' else doc.party_name }},<br>
          Thank you for your interest in our order.</p>
        </div>
        <div class="section-break">

          <!-- ITEM TABLE -->
          <table style="width: 100%; font-size: 10pt; border-collapse: collapse; margin-top: 30px;">
            <thead>
              <tr style="background-color: #f5f5f5;">
                <th style="padding: 6px; border: 1px solid #ccc;">#</th>
                <th style="padding: 6px; border: 1px solid #ccc;">Item Code</th>
                <th style="padding: 6px; border: 1px solid #ccc;">Qty</th>
                <th style="padding: 6px; border: 1px solid #ccc;">UOM</th>
                <th style="padding: 6px; border: 1px solid #ccc;">Rate</th>
                <th style="padding: 6px; border: 1px solid #ccc;">Amount</th>
              </tr>
            </thead>
            <tbody>
              {% for item in doc.items %}
              <tr {% if loop.index == 1 %}style="page-break-inside: avoid;"{% endif %}>
                <td style="padding: 6px; border: 1px solid #ccc;">{{ loop.index }}</td>
                <td style="padding: 6px; border: 1px solid #ccc;">
                  <div>{{ item.item_code }}</div>
                  <div style="font-size: 9pt; color: #555; white-space: pre-wrap; word-break: break-word;">
                    {{ item.description or '' }}
                  </div>
                </td>
                <td style="padding: 6px; border: 1px solid #ccc; text-align: right;">{{ item.qty }}</td>
                <td style="padding: 6px; border: 1px solid #ccc;">{{ item.uom }}</td>
                <td style="padding: 6px; border: 1px solid #ccc; text-align: right;">{{ item.rate }}</td>
                <td style="padding: 6px; border: 1px solid #ccc; text-align: right;">{{ item.amount }}</td>
              </tr>
              {% endfor %}
            </tbody>
          </table>
        </div>
    </div>

</div>
{% endfor %}

Custom Letter Head

// Header
<div style="width: 100%; font-size: 10pt; padding-bottom: 5px;">
  <table style="width: 100%;">
    <tbody><tr>
      <td style="width: 60%; vertical-align: top;">
        <strong>Company Name</strong><br>
        Near, NY Tower<br>
        Bldg 42<br>
        37392 Milan<br>
        Italy
      </td>
      <td style="width: 40%; text-align: right;">
        <img src="http://site-name.com:8013/files/sample-logo.jpg" alt="Test Company" style="max-height: 60px;"><br>
        <span style="font-size: 9pt;">Technology for Behaviour Analysis</span>
      </td>
    </tr>
  </tbody></table>
  <hr style="margin: 5px 0;">
</div>

// Footer
<div style="width: 100%; font-size: 8pt; margin-top: 10px;">
  <table style="width: 100%;">
    <tbody><tr>
      <td style="width: 25%; vertical-align: top;">
        <strong>Company Name</strong><br>
        Near, NY Tower<br>
        Bldg 42<br>
        37392 Milan<br>
        Italy
      </td>
      <td style="width: 25%; vertical-align: top;">
        <strong>Phone:</strong> +82 7282927287<br>
      </td>
      <td style="width: 25%; vertical-align: top;">
        <strong>Bank:</strong> US BANK<br>
        <strong>Bank Code:</strong> 839 8398 838<br>
        <strong>Account:</strong> 89272 83982 723<br>
        <strong>IBAN:</strong> IT012 7389 927 839 8382 82<br>
        <strong>SWIFT:</strong> BELADEBE
      </td>
    </tr>
  </tbody></table>
</div>


Thank you in advance!
Really appreciate any suggestions or working examples if anyone have!

1 Like