ERPNext (wkhtmltopdf) PDF Generates Incorrect Layout (Font Size, Margins, Page Size)

I’m facing an issue in ERPNext when generating PDFs from the Sales Invoice print screen. There are two options for PDF generation:

  1. Print → Save as PDF (Works perfectly, maintains layout and everything)
  2. Direct PDF Button (Breaks layout: font size, margins, and page size change)

I tried modifying the Print Settings CSS, which affects both methods. While some changes reflect, it also disrupts the “Print → Save as PDF” output.

I’ve searched and found similar issues, but the solutions are not working in my case as maybe it’s outdated or I’ve different version of Erpnext/Frappe/wkhtmltopdf etc.

What I’ve Found:

What I’ve Tried, Resolved:

  • Adjusting CSS in Print Settings
  • Ensuring wkhtmltopdf is correctly installed (using the Qt-patched version 0.12.6)
  • Added “host_name”: “example.com, in sitename/site_config.json and ran command bench migrate
  • In my case, pictures (QR, Header, Footer) are displayed, so no issue with paths

Questions:

  1. How can I apply styles specifically to the PDF button output without affecting Print → Save as PDF?
  2. Any ERPNext configuration changes needed to standardize both outputs?

I’ve attached both screenshots:


You’ll notice the difference of Font Size, Font Family, Overlapping of texts, Page Size etc.

I’ve also attached the Print Format to understand the css applied.

Print Format .print-format table, .print-format tr, .print-format td { font-family: serif; line-height: 0.3 !important; vertical-align: middle; direction: rtl !important; } @media print { body { font-family: 'Cairo'; width: 220mm; height: 297mm; margin: 5mm 5mm 10mm 5mm; footer { page-break-after: always; } /* change the margins as you want them to be. */ } } @media screen { .print-format { width: 200mm; padding: 5mm; min-height: 297mm; footer { page-break-after: always; } } } table { width: 100%; white-space: nowrap; } th { font-size: 10px; color: black; } body:last-child .print-format td img { width: 60% !important; } .ql-editor read-mode { line-height: 1 !important; } .ql-editor p, .ql-editor h1, .ql-editor h2, .ql-editor h3, .ql-editor h4, .ql-editor h5, .ql-editor h6, .ql-editor span { counter-reset: list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; line-height: 1.2; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; display: inline-flex !important; } .print-format p { margin: 3px 0px 3px; display: inline-block !important; } .si { color: darkblue !important; margin-top: -5px !important; } .w1 {} .w2 { border-top: 3px solid #d1d8dd !important; padding-top: 4px !important; text-align: center; direction: rtl; margin-top: 15px; } @media print { div.print-footer { display:block !important; position: fixed !important; bottom: 0; width: 97%; background-color: white; text-align: center; padding: 2mm 2; box-sizing: border-box; page-break-after: always; z-index: 9999; } div.print-footer .page-number { position: absolute; bottom: 5mm; width: 100%; text-align: center; } @page :first { table:nth-of-type(4) tr:nth-child(n+10) { page-break-after: always; } } @page { table tr:nth-child(28n+1) { page-break-after: always; } } } * { box-sizing: content-box !important; } body { counter-reset: page; } /* Define a style for the page number */ .page-number:before { counter-increment: page; content: counter(page) " of "counter(pages); }
<table style="white-space: nowrap;margin-top:-4% !important;">
    <tr>
        <td style="width:50%;">
            <!-- Table2 -->
            <table style="white-space: nowrap;line-height: 1.3 !important;">
                <tr style="line-height: 1.3 !important;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <span style="color: #5b5b5b;font-size: 25px;font-weight: 800;text-align: center;line-height: 1;">
							<br> {{ "TAX INVOICE" }}
							<br> {{ "فاتورة ضريبية " }}
						</span>
                    </td>
                </tr>
            </table>
        </td>
        <td style="width:10%;">
            <!-- Table1 -->
            <table>
                <tr>
                    <td>
                        <div style="width: 200px !important;text-align: center; display: block !important;margin: 0 149px 0 -13px!important;vertical-align: middle !important;margin-top: 0px !important;"> 
                        {{ letter_head }}</div>
                    </td>
                </tr>
            </table>
</table>
<table style="white-space: nowrap;table-layout: fixed;">
    <tr>
        <td style="width:50%;">
            <!-- Table1 -->
            <table style="white-space: nowrap;table-layout: fixed;">
                <tr>
                    <td>
                        <div style="width: 200px !important;text-align: center; display: block !important;margin: 0 auto !important;vertical-align: middle !important;margin-top: -25px !important;">
                            <img class="qr-code" src={{doc.ksa_einv_qr}}>
                        </div>
                    </td>
                </tr>
            </table>
        </td>
        <td style="width:50%; border: solid 2px gray; ">
            <!-- Table2 -->
            <table style="white-space: nowrap;table-layout: fixed;line-height: 1.3 !important;">
                <tr style="line-height: 1.3 !important;">
                    <td style="width:30%;font-size: 10px;text-align: left;line-height: 1.3 !important;">
                        <b>{{ "رقم الفاتورة" }} :</b>
                        <br>
                        <b>{{ "تاريخ الفاتورة" }} :</b>
                        <br>
                        <b>{{ "رقم العقد " }} :</b>
                        <br>
                        <b>{{ "رقم أمر الشراء/الخدمة " }} :</b>
                        <br>
                        <b>{{ " تاريخ التوريد/الإنجاز " }} :</b>
                        <br>
                        <b>{{ "الرقم المرجعي " }} :</b>
                        <br>
                        <b>{{ "رمز البائع " }} :</b>
                        <br>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: center;line-height: 1.3 !important;">
                        <b style="color: darkblue;">{{ doc.name }}</b>
                        <br>
                        <b style="color: darkblue;"> {{ doc.get_formatted("posting_date") }}</b>
                        <br>
                        <b style="color: darkblue;">{{ doc.custom_contract_number or "" }}</b>
                        <br>
                        <b style="color: darkblue;">{{ doc.po_no or "" }}</b>
                        <br>
                        <b style="color: darkblue;">{{ doc.delivery_date_and_time or "" }}</b>
                        <br>
                        <b style="color: darkblue;">{{ doc.custom_rfx_number or "" }}</b>
                        <br>
                        <b style="color: darkblue;">{{ doc.custom_vendor_no or "" }}</b>
                        <br>
                    </td>
                    <td style="width:35%;font-size: 10px;text-align: right;line-height: 1.3 !important;">
                        <b>:{{ "Invoice No" }}</b>
                        <br>
                        <b>:{{ "Invoice Date" }}</b>
                        <br>
                        <b>:{{ "Contract Number" }}</b>
                        <br>
                        <b>:{{ "Order/Service No" }}</b>
                        <br>
                        <b>:{{ "Complet/Delivery Date" }}</b>
                        <br>
                        <b>:{{ " P.T.Ref" }}</b>
                        <br>
                        <b>:{{"Vender No " }}</b>
                        <br>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
<table style="white-space:nowrap; table-layout:fixed; margin-top:5px; width:100%; text-align:center;">
    <tr>
        <td style="width:50%; border:2px solid gray;">
            <!-- Table1 -->
            <table style="white-space: nowrap; table-layout: fixed; margin-top: -6px; width:100%;">
                <tr style="border-bottom: 2px solid black;">
                    <td style="width:35%; font-size:16px; font-weight:900; text-align:right;"></td>
                    <td style="width:80%; font-size:12px; font-weight:900; text-align:center;">
                        <b> {{ " Supplier " }}</b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b> {{ " المورد" }} </b>
                    </td>
                    <td style="width:35%; font-size:16px; font-weight:900; text-align:left;"></td>
                </tr>
                <tr style="border-bottom:1px solid black;">
                    <td colspan="3" style="font-size:10px; text-align:center;">
                        <b style="color: darkblue;">{{ "شركة الرواد الفنية للتجارة والمقاولات العامه المحدوده" }}</b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b style="color: darkblue;">{{ "Pioneers Technical For Trading & General Contracting Co. Ltd" }}</b>
                    </td>
                </tr>
                <tr style="border-bottom: 1px solid black;">
                    <td style="width:30%; font-size:10px; text-align:right;">
                        <b>{{ "الرقم الضريبي" }}:</b>
                    </td>
                    <td style="width:40%; font-size:10px; text-align:center; color:darkblue;">
                        <b>{{ doc.company_tax_id }}</b>
                    </td>
                    <td style="width:30%; font-size:10px; text-align:left;">
                        <b>:{{ "VAT ID" }}</b>
                    </td>
                </tr>
                
                
                <tr style="border-bottom: 1px solid black;">
                    <td style="width:25% !important; font-size:10px; text-align:center;">
                        <div style="font-weight:900; padding: 5px; border-bottom: 1px solid black;">
                                ترخيص الموارد البشرية
                        </div>
                        <div style="padding: 5px;">
                                85953
                        </div>
                        
                    </td>
                    <td style="width:25% !important; font-size:10px; text-align:center;">
                        <div style="font-weight:900; padding: 5px; border-bottom: 1px solid black;">
                                السجل التجاري (CR)
                        </div>
                        <div style="padding: 5px;">
                                4030138666
                        </div>
                    </td>
                    <td style="width:25% !important; font-size:10px; text-align:center;">
                        <div style="font-weight:900; padding: 5px; border-bottom: 1px solid black;">
                                التامينات الاجتماعية
                        </div>
                        
                        <div style="padding: 5px;">
                                511414695
                        </div>
                    </td>

                </tr>
 
                
                <tr>
                    <td style="width:30%; font-size:10px; text-align:right; height:75px;">
                        <b>{{ "العنوان" }}:</b>
                    </td>
                    <td style="width:40%; font-size:10px; text-align:center; height:75px; line-height:1 !important; color:darkblue;">
                        <b style="white-space: normal !important;color: darkblue !important;"> {{ frappe.db.get_value("Address", doc.company_address, "address_line1") or "" }}
							<br>
							<br> {{ frappe.db.get_value("Address", doc.company_address, "address_in_arabic") or "" }}
						</b>
                    </td>
                    <td style="width:30%; font-size:10px; text-align:left; height:75px;">
                        <b>:{{ "Address" }}</b>
                    </td>
                </tr>
            </table>
        </td>
        <td style="width:50%; border:2px solid gray;">
            <!-- Table2 -->
            <table style="white-space:nowrap; table-layout:fixed; margin-top:-6px; width:100%;">
                <tr style="border-bottom: 2px solid black;">
                    <td style="width:35%; font-size:16px; font-weight:900; text-align:right;"></td>
                    <td style="width:80%; font-size:12px; font-weight:900; text-align:center;">
                        <b> {{ " Customer " }}</b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b> {{ " العميل" }} </b>
                    </td>
                    <td style="width:35%; font-size:16px; font-weight:900; text-align:left;"></td>
                </tr>
                <tr style="border-bottom:1px solid black;">
                    <td colspan="3" style="font-size:10px; text-align:center;">
                        <b style="color: darkblue;">{{ doc.customer_name_in_arabic or "" }} </b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b style="color: darkblue;">{{ doc.customer_name }} </b>
                    </td>
                </tr>
                <tr style="border-bottom:1px solid black;">
                    <td style="width:30%; font-size:10px; text-align:right;">
                        <b>{{ "الرقم الضريبي" }}:</b>
                    </td>
                    <td style="width:40%; font-size:10px; text-align:center; color:darkblue;">
                        <b>{{ doc.tax_id or "" }}</b>
                    </td>
                    <td style="width:30%; font-size:10px; text-align:left;">
                        <b>:{{ "VAT ID" }}</b>
                    </td>
                </tr>
                
				<tr style="border-bottom:1px solid black;">
					<td style="width:30%; font-size:10px; text-align:right;">
						<b>{{ "رقم السجل التجاري"}}:</b>
					</td>
					<td style="width:40%; font-size:10px; text-align:center; color:darkblue;">
						<b>{{ frappe.get_doc("Customer", doc.customer).custom_company_cr or ""}} </b>
					</td>
					<td style="width:30%; font-size:10px; text-align:left;">
						<b>:{{ "CR NO" }}</b>
					</td>
				</tr>
                
                <tr>
                    <td style="width:30%; font-size:10px; text-align:right; height:75px;">
                        <b>{{ "العنوان" }}:</b>
                    </td>
                    <td style="width:40%; font-size:10px; text-align:center; height:75px; line-height:1 !important; color:darkblue;">
                        <b style="white-space: normal !important;color: darkblue !important;"> {{ frappe.db.get_value("Address", doc.customer_address, "address_line1") or "" }}
							<br>
							<br> {{ frappe.db.get_value("Address", doc.customer_address, "address_in_arabic") or "" }}
						</b>
                    </td>
                    <td style="width:30%; font-size:10px; text-align:left; height:75px;">
                        <b>:{{ "Address" }}</b>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>




<!--Dynamic Colspan for total row columns-->
{% set col = namespace(one = 2, two = 1) %} {% set length = doc.taxes | length %} {% set length = length / 2 | round %} {% set col.one = col.one + length %} {% set col.two = col.two + length %} {%- if(doc.taxes | length % 2 > 0 ) -%} {% set col.two =
col.two + 1 %} {% endif %}
<!-- Items -->
{% set total = namespace(amount = 0) %}
<table style="margin-top: 15px;direction: ltr !important;white-space:nowrap; table-layout:fixed;">
    <thead>
        <tr style="border-bottom: solid 2px black;border-top: solid 2px black;line-height: 2 !important;">
            <th colspan="1" style="width:3%;text-align:center;color:black;font-size:12px;font-weight: 600;">S
                <br>م </th>
            <th colspan="3" style="width:57%;text-align:center;color:black;font-size:12px;font-weight: 600;">Description
                <br>وصف المنتج </th>
            <th colspan="1" style="width:5%;text-align:center;color:black;font-size:12px;font-weight: 600;">QTY
                <br>الكمية </th>
            <th style="width:10%;text-align:left;color:black;font-size:12px;font-weight: 600;">Unit Price
                <br>سعر الوحدة </th>
            <th style="width:15%;text-align:left;color:black;font-size:12px;font-weight: 600;">Taxable Amount
                <br />الاجمالي قبل الضريبة </th> {% for row in doc.taxes %}
            <th style="width:15%;text-align:center;color:black;font-size:12px;font-weight: 600;">Tax Percentage
                <br>نسبة الضريبة </th>
            <th style="width:10%;text-align:center;color:black;font-size:12px;font-weight: 600;">Tax Amount
                <br>مبلغ الضريبة </th> {% endfor %}
            <th style="width:15%;text-align:center;color:black;font-size:12px;font-weight: 600;">Total With VAT
                <br>المجموع بالضريبة </th>
        </tr>
    </thead>
    <tbody>
        {%- for item in doc.items -%} {% set total.amount = item.amount %}
        <tr style="margin-bottom: -10px !important;line-height:0.1 !important; height: 20px !important;">
            <td colspan="1" style="width: 2%;text-align: center;">{{ item.idx }}</td>
            <td colspan="3" style="width: 40%;text-align: left;line-height:0.3!important;font-size: 11px;font-weight: 700;">{{ item.item_code }}</td>
            <td colspan="1" style="text-align: center;font-size: 12px;font-weight: 700;">{{ item.qty }}</td>
            <td style="text-align: left;font-size: 12px;font-weight: 700;">{{ item.get_formatted("rate") }}</td>
            <td style="text-align: left;font-size: 12px;font-weight: 700;">{{ item.get_formatted("amount") }}</td>
            {% for row in doc.taxes %} {% set data_object = json.loads(row.item_wise_tax_detail) %} {% set key = item.item_code or item.item_name %} {% set taxable_amount = item.amount %} {% set tax_percentage = data_object[key][0] or 0 %} {% set tax_amount = taxable_amount
            * (tax_percentage / 100) %} {% set total.amount = total.amount + tax_amount %}
            <td style="text-align: center;font-size: 12px;font-weight: 700;">
                <div class="qr-flex"> {%- if data_object[key][0] -%} <span>{{ frappe.format(data_object[key][0], {'fieldtype': 'Percent'}) }}</span> {%- endif -%} </div>
            </td>
            <td style="text-align: center;font-size: 12px;font-weight: 700;">
                <span> {% if data_object[key][0] %} {{ frappe.format_value(tax_amount, currency=doc.currency) }} {% endif %} </span>
            </td> {% endfor %}
            <td style="text-align: center;font-size: 12px;font-weight: 700;"> {{ frappe.format_value(frappe.utils.flt(total.amount, doc.precision('total_taxes_and_charges')), currency=doc.currency) }} </td>
        </tr>
        <tr style="border-bottom: solid 1px gray;height: 20px !important;font-size: 11px;font-weight: 700;margin-top:-1% !important">
            <td> </td>
           <td colspan="10" style="width: 60%; text-align: left; font-size: 10px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
{{ item.description.replace('\n', ' ').replace('\r', '').replace('\t', '+').replace('  ', '+').strip() }}
        </tr>
        {%- endfor -%}
    </tbody>
</table>



<table style="white-space: nowrap;table-layout: fixed;margin-top: 5px;">
    <tr>
        <td style="width:50%; border: solid 2px gray; ">
            <!-- Table1 -->
            <table style="white-space: nowrap;table-layout: fixed;margin-top: -6px;">
                <tr style="border-bottom: solid 2px black;">
                    <td style="width:30%;font-size: 16px;font-weight: 900;text-align: right;">
                        <b>{{ " اجمالي المبالغ" }}:</b>
                    </td>
                    <td style="width:40%;font-size: 10px;"></td>
                    <td style="width:30%;font-size: 16px;font-weight: 900;text-align: left;">
                        <b>:{{ " Total Amount" }}</b>
                    </td>
                </tr style="line-height: .4 !important;">
                <tr style="border-bottom: solid 1px gray;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <b> {{ doc.get_formatted("total", doc) }} </b>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: right;">
                        <b>{{ "الاجمالي غير شامل ضريبة القيمة المضافة"}}</b>
                    </td>
                    <td style="width:30%;font-size: 10px;text-align: left;">
                        <b>
							<b>{{ " Total Without Tax " }}</b>
                        </b>
                    </td>
                </tr>
                <tr style="border-bottom: solid 1px gray;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <b> {{ doc.get_formatted("discount_amount") }} </b>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: right;">
                        <b>{{ "اجمالي الخصومات "}}</b>
                    </td>
                    <td style="width:30%;font-size: 10px;text-align: left;">
                        <b>
							<b>{{ ("Total Discount") }}</b>
                        </b>
                    </td>
                </tr>
                <tr style="border-bottom: solid 1px gray;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <b> {{ doc.get_formatted("net_total", doc) }} </b>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: right;">
                        <b>{{ "الاجمالي الخاضع لضريبة القيمة المضافة "}}</b>
                    </td>
                    <td style="width:30%;font-size: 10px;text-align: left;">
                        <b>
							<b>{{ (" Total Taxable Amount ") }}</b>
                        </b>
                    </td>
                </tr>
                <tr style="border-bottom: solid 1px gray;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <b> {{ doc.get_formatted("total_taxes_and_charges", doc) }}</b>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: right;">
                        <b>{{ "مجموع ضريبة القيمة المضافة "}}</b>
                    </td>
                    <td style="width:30%;font-size: 10px;text-align: left;">
                        <b>
							<b>{{ (" Total VAT ") }}</b>
                        </b>
                    </td>
                </tr>
                <tr style="border-bottom: solid 1px gray;">
                    <td style="width:30%;font-size: 10px;text-align: center;">
                        <b> {{ doc.get_formatted("grand_total") }} </b>
                    </td>
                    <td style="width:40%;font-size: 10px;text-align: right;">
                        <b>{{ "اجمالي المبلغ المستحق "}}</b>
                    </td>
                    <td style="width:30%;font-size: 10px;text-align: left;">
                        <b>
							<b>{{ (" Total Amount Due ") }}</b>
                        </b>
                    </td>
                </tr>


                <tr>

                    <td colspan="3" style="width:40%; font-size:10px; text-align:center; line-height:1 !important;">
                        <b style="white-space: normal !important;"> {{frappe.utils.money_in_words(doc.grand_total).replace('SAR', '').rstrip('only.') ~ ' Saudi Rayals Only'}}
                </tr>

            </table>
        </td>
        <td style="width:50%;border: solid 2px gray;">
            <!-- Table1 -->
            <table style="width:100%; text-align:center; white-space:nowrap; table-layout:fixed; margin-top:-6px;">
                <tr style="border-bottom:2px solid gray;">
                    <td style="width:20%; font-size:16px; font-weight:900; text-align:right;">
                        <b>{{ "تفاصيل البنك"}}:</b>
                    </td>
                    <td style="width:40%; font-size:16px;"></td>
                    <td style="width:35%; font-size:16px; font-weight:900; text-align:left;">
                        <b>:{{ "Bank Info"}}</b>
                    </td>
                </tr>
                <tr style="border-bottom:1px solid gray;">
                    <td colspan="3" style="font-size:12px; font-weight:900; height:35px;">
                        <b style="margin-left: 50px;">{{ "اسم الحساب المصرفي" }}</b>
                        <b>{{ "Bank Name"}}</b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b style="font-size: 8px;font-weight: 900;">{{ "PIONEERS TECHNICAL FOR TRADING AND GENERAL CONTRACTING CO. LTD"}}</b>
                        <br>
                        <br>
                        <br>
                        <br>
                        <br>
                        <b>{{ "شركة الرواد الفنية للتجارة والمقاولات العامة المحدودة"}}</b>
                    </td>
                </tr>
                <tr style="border-bottom:1px solid gray;">
                    <td colspan="3" style="font-size:10px; text-align:center;">
                        <b style="margin-left: 180px;">{{ "ايبان بنك الرياض" }}:</b>
                        <b>:{{ "RB IBAN NO"}}</b>
                        <br>
                        <br>
                        <br>
                        <b style="color: darkblue;font-size: 12px;">{{ "SA59 2000 0001 6916 2321 9940"}}</b>
                    </td>
                </tr>
                <tr style="border-bottom:1px solid gray;">
                    <td colspan="3" style="font-size:10px; text-align:center;">
                        <b style="margin-left: 180px;">{{ "ايبان البنك الاهلي" }}:</b>
                        <b>:{{ "SNB IBAN NO"}}</b>
                        <br>
                        <br>
                        <br>
                        <b style="color: darkblue;font-size: 12px;">{{ "SA71 1000 0012 9566 0400 0107"}}</b>
                    </td>
                </tr>
        </td>
    </tr>
    </table>
    </td>
    </tr>
</table>

<div class="print-footer"> {{ footer }}
    
</div>

Would appreciate any guidance from the community! Thanks.