How to define Left and Right Margin for PDF and Print

Hi @Muthu,

Thanks for sharing your code, but for me the code is not working at all.
See this:

PDF with left margin 0mm:

PDF with left margin 5mm:

Regards
Ruchin Sharma

Hi @ruchin78

Set left margin to 12mm and check

Thanks

@Muthu
See the screenshot below with 12mm left margin:

I want a small amount of left margin whereas it is huge and doesn’t fulfill my requirement.

Regards
Ruchin Sharma

@ruchin78 .

It is just a trial and error method ,if 12mm is not ok then try 8mm ,play with it for some time and you will be able to achieve what you want .

Thanks

@Muthu

I tried every way with every possible way with every permutation combination but it doesn’t fulfill my requirement and that is what I said in the beginning too.

Anyways, thanks for your help.

Regards
Ruchin Sharma

Hi, the same issue here. Any solution @ruchin78?

thanks!

@ruchin78, @federico_calvo

Try the following code this should work.

<div id="header-html" class="hidden-pdf">
    <div id="variables" style="display:none;">
        <span id="margin-top">1mm</span>
    <span id="margin-left">5mm</span>
    <span id="margin-right">5mm</span>
    <span id="margin-bottom">0mm</span>
    </div>   
</div>
1 Like

It’s really work. thank you so much.

1 Like

Hi @anandhuded2 and @vinhnguyent090, could either of you show me a complete example of a pdf with this code working? Since I can’t find out what my mistake is.

Thank you!

Hi

print html file I add end of file.
example file of my app:

<div id="header-html" class="hidden-pdf">
    <div id="variables" style="display:none;">
        <span id="margin-top">7mm</span>
    	<span id="margin-left">0mm</span>
    	<span id="margin-right">0mm</span>
    	<span id="margin-bottom">7mm</span>
    </div>
</div>
1 Like

Thank you for sharing, in my case it’s a print format, not a custom html report.

Provides several ways to place it at the end but does not work.

If it’s not the same maybe you should make a post (already check all the referred posts in pdf margins)

Regards!

1 Like

@federico_calvo

It should work for all the custom print formats.

In your case also it should work.

If not share your code here.

Hi @anandhuded2, thanks for response.

I enclose the code for example, it provides many forms without result

<header>
  <table class="table table-bordered">
    <tr>
      <td class="text-center" width="15%">
        <img src="/files/logo-chico.png" width="100">
      </td>
      <td>
        <h5 class="text-center">INGRESO DE MUESTRAS</h5>
      </td>
      <td>
        <small>RG 046 <br>Rev. Nº: 05 <br>{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}<br> 02/01/2018</small>
      </td>
    </tr>
  </table>
  <p><small><b>Origen: PT 5.8 ¨Manipulación de las muestras¨</b></small></p>
  <h6 class="text-center"><b>FORMULARIO DE ENVIO Nº {{ doc.name}}-{{ _("{0}").format('<span class="page"></span>', '<span class="topage"></span>') }}</b></h6>
  <div class="row">
  	<div class="col-xs-4">
  		<p><u>ENVIO:</u> {{ doc.name }}</p>
  		
    </div>
    <div class="col-xs-8">
  		<p><u>PLANTA:</u> {{ doc.planta }}</p>
  		
    </div>
   </div>
   <div class="row">
   	<div class="col-xs-4">
  		<p><u>RESPONSABLE: </u>{{ doc.responsable }}</p>
    </div>
    <div class="col-xs-4">
  		<p><u>Fecha Recepción:</u>{{ doc.fecha_ingreso}}</p>
    </div>
    <div class="col-xs-4">
  		<p><u>Inicio de Análisis:</u>{{doc.fecha_inicio}}</p>
    </div>
</header>

<div>
	<table class="table">
  		<thead>
  			<th width="30%">IDENTIFICACION DE MUESTRA</th>
  			<th width="50%">DETERMINACION</th>
  			<th width="20%">TECNICA</th>
  		</thead>
  		<tbody>
  			{% for muestra in doc.get_muestras() %}
    
  			<tr>
  				<td><b>{{muestra.name}}</b>-{{ muestra.descripcion}} </td>
  				<td> {% set analisis = frappe.get_all('Muestra Analisis', {'parent': muestra.name}, ['item_name']) %}
  					{% for anali in analisis %}
  						{{ anali.item_name }}<br>
  					{% endfor %}
  				</td>
  				<td>{% set analisis = frappe.get_all('Muestra Analisis', {'parent': muestra.name}, ['tecnica']) %}
  					{% for anali in analisis %}
  						{{ anali.tecnica or '' }}<br>
  					{% endfor %}

  				</td>
  			</tr>
  			{% endfor %}
  		</tbody>
	</table>
</div>
<div class="row">
	<div class="col-xs-12">
			{% if doc.workflow_state == 'Validado' or doc.workflow_state == 'Facturado' %}
      {% set usuario_validacion = frappe.get_doc("User", doc.usuario_validacion, 'username') %}
        {% if usuario_validacion.username == 'ResponsableCalidad' %}  
        <div style="position: absolute;right:10px;">
          <img src="/files/firma-validacion.png" style="width:140px;">
          <p><b>{{ frappe.utils.formatdate(frappe.utils.today(), 'd  M  Y') }}</b></p>
        </div>
        {% elif  usuario_validacion.username == 'ResponsableCalidad2' %}
          <div style="position: absolute;right:10px;">
          <img src="/files/firma-validacion-2.png" style="width:140px;">
          <p><b>{{ frappe.utils.formatdate(frappe.utils.today(), 'd  M  Y') }}</b></p>
          </div>
        {% else %}
        {% endif %}
      {% endif %}
	</div>
</div>
<div id="header-html" class="hidden-pdf">
    <div id="variables" style="display:none;">
        <span id="margin-top">5mm</span>
      <span id="margin-left">0mm</span>
      <span id="margin-right">0mm</span>
      <span id="margin-bottom">5mm</span>
    </div>
</div>

And the result:

hi @vinhnguyent090 and @anandhuded2, Can you confirm that you put the code in the same way?

Thank you and excuse the inconvenience.

Regards!

@federico_calvo

You can try some thing like this. Just copy and paste below code it should work.

<!DOCTYPE html>
<html>
<head>
    <div id="header-html" class="hidden-pdf">
        <div id="variables" style="display:none;">
            <span id="margin-top">1mm</span>
            <span id="margin-left">5mm</span>
            <span id="margin-right">5mm</span>
            <span id="margin-bottom">0mm</span>
        </div>
    </div>
  

</head>
<body>

    <header>
  <table class="table table-bordered">
    <tr>
      <td class="text-center" width="15%">
        <img src="/files/logo-chico.png" width="100">
      </td>
      <td>
        <h5 class="text-center">INGRESO DE MUESTRAS</h5>
      </td>
      <td>
        <small>RG 046 <br>Rev. Nº: 05 <br>{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}<br> 02/01/2018</small>
      </td>
    </tr>
  </table>
  <p><small><b>Origen: PT 5.8 ¨Manipulación de las muestras¨</b></small></p>
  <h6 class="text-center"><b>FORMULARIO DE ENVIO Nº {{ doc.name}}-{{ _("{0}").format('<span class="page"></span>', '<span class="topage"></span>') }}</b></h6>
  <div class="row">
    <div class="col-xs-4">
        <p><u>ENVIO:</u> {{ doc.name }}</p>
        
    </div>
    <div class="col-xs-8">
        <p><u>PLANTA:</u> {{ doc.planta }}</p>
        
    </div>
   </div>
   <div class="row">
    <div class="col-xs-4">
        <p><u>RESPONSABLE: </u>{{ doc.responsable }}</p>
    </div>
    <div class="col-xs-4">
        <p><u>Fecha Recepción:</u>{{ doc.fecha_ingreso}}</p>
    </div>
    <div class="col-xs-4">
        <p><u>Inicio de Análisis:</u>{{doc.fecha_inicio}}</p>
    </div>
</header>

<div>
    <table class="table">
        <thead>
            <th width="30%">IDENTIFICACION DE MUESTRA</th>
            <th width="50%">DETERMINACION</th>
            <th width="20%">TECNICA</th>
        </thead>
        <tbody>
            {% for muestra in doc.get_muestras() %}
    
            <tr>
                <td><b>{{muestra.name}}</b>-{{ muestra.descripcion}} </td>
                <td> {% set analisis = frappe.get_all('Muestra Analisis', {'parent': muestra.name}, ['item_name']) %}
                    {% for anali in analisis %}
                        {{ anali.item_name }}<br>
                    {% endfor %}
                </td>
                <td>{% set analisis = frappe.get_all('Muestra Analisis', {'parent': muestra.name}, ['tecnica']) %}
                    {% for anali in analisis %}
                        {{ anali.tecnica or '' }}<br>
                    {% endfor %}

                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
<div class="row">
    <div class="col-xs-12">
            {% if doc.workflow_state == 'Validado' or doc.workflow_state == 'Facturado' %}
      {% set usuario_validacion = frappe.get_doc("User", doc.usuario_validacion, 'username') %}
        {% if usuario_validacion.username == 'ResponsableCalidad' %}  
        <div style="position: absolute;right:10px;">
          <img src="/files/firma-validacion.png" style="width:140px;">
          <p><b>{{ frappe.utils.formatdate(frappe.utils.today(), 'd  M  Y') }}</b></p>
        </div>
        {% elif  usuario_validacion.username == 'ResponsableCalidad2' %}
          <div style="position: absolute;right:10px;">
          <img src="/files/firma-validacion-2.png" style="width:140px;">
          <p><b>{{ frappe.utils.formatdate(frappe.utils.today(), 'd  M  Y') }}</b></p>
          </div>
        {% else %}
        {% endif %}
      {% endif %}
    </div>
</div>   
      
        
</body>
</html>
1 Like

Yeah… that only appears to work with direct printing. When making PDFs the padding is defined in pdf.py and it only seems to be able to change from there. However, if you zero out the padding in pdf.py, then you can add it back for printing using your method (although in reverse I guess).

This padding is most annoying when trying to print to a 80mm wide receipt printer. The print function of POS creates the PDF file and sends it to the printer rather than using the printer drivers. Not sure why it works that way, but it means that unless you alter the pdf.py your receipts will all be pushed into the middle 36mm of a 80mm thermal printer.

So use @Nikesh_Bhansali post above, and then use your method to put the margins back when printing.

BKM

hi bkm, yes, but that solution involves touching erpnext code would be inutized at the time of updating.

A few days ago we made a post to make these variables self-administrable. Today we are going to upload the pull request and if you think it’s right, support us to integrate it.

We find it hard to believe that there aren’t many users claiming this because the pdf files are the ones sent by email, those that allow repeating header and footer, those that allow using the page number functions, etc…

Regards!

If you are only going to set the top and bottom margin to variables, then the job would be incomplete. Most of us do not care about the top and bottom nearly as much as left and right. I would only really support the PR if it included all 4 margins.

You see, the top and bottom do not affect POS receipts very much. However, when using a thermal receipt printer, the data is first converted to a temporary PDF and sent to the printer that way. This means the forced padding is reflected in the little 80mm wide receipt tape. It forces everything into the center 37mm of an 80mm wide paper receipt. This affects everyone that uses the POS module.

For that reason, I can only support your idea if it allows all 4 margins to be edited without touching the core code.

BKM

2 Likes

i’m getting error when generating pdf after margin-top has given



Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 95, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 55, in handle
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 48, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 86, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1619, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/utils/print_format.py", line 130, in download_pdf
    pdf_file = frappe.get_print(
  File "apps/frappe/frappe/__init__.py", line 2049, in get_print
    return get_pdf(html, options=pdf_options, output=output) if as_pdf else html
  File "apps/frappe/frappe/utils/pdf.py", line 43, in get_pdf
    filedata = pdfkit.from_string(html, options=options or {}, verbose=True)
  File "env/lib/python3.10/site-packages/pdfkit/api.py", line 75, in from_string
    return r.to_pdf(output_path)
  File "env/lib/python3.10/site-packages/pdfkit/pdfkit.py", line 201, in to_pdf
    self.handle_error(exit_code, stderr)
  File "env/lib/python3.10/site-packages/pdfkit/pdfkit.py", line 158, in handle_error
    raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg))
OSError: wkhtmltopdf exited with non-zero code 1. error:
Exit with code 1, due to unknown error.