Search code examples
pythonhtmldjangopdfxhtml2pdf

How to export arabic characters to pdf in xhtml2pdf?


I want to export arabic characters to pdf using xhtml2pdf, cause I'm using it in my django app.

I know that they made an update saying that they fixed it, but it didn't work with me, I used a custom font but still not working.

So please anyone knows the right encryption for this or anyway around it, help me.

invoice.html :

{% load static %}

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
<head>
    <title>{{title}}</title>
<style type="text/css">
        @font-face {
        font-family: Amiri, "Amiri Font";
        src: url("{% static 'font/Amiri-Italic.ttf'%}");
        }
        body {
            font-weight: 200;
            font-size: 14px;
        }

    </style>
</head>

<body><pdf:language name="arabic"/>
    <div class='wrapper'>
        <div class='header'>
            <p class='title'>Invoice # {{ invoice_ID }} </p>
        </div>
        <div>
            <div class='details'>

                <pdf:language name="arabic"/>     
                <p> تجربة</p>           
                customername : {{customer_name}} <br><hr>
                <hr class='hrItem' />
            </div>
        </div>
</body>

</html>

utils.py :

from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template

from xhtml2pdf import pisa

def render_to_pdf(template_src, context_dict={}):
    template = get_template(template_src)
    html  = template.render(context_dict)
    result = BytesIO()
    pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result)
    if not pdf.err:
        return HttpResponse(result.getvalue(), content_type='application/pdf')
    return None

views.py :

from django.shortcuts import render, redirect, HttpResponse
import pandas as pd
from .models import SaleInvoice, TransferWays, User, InstallingCities
from siteManagment.models import MarketersManagment, WareHouses
from .utils import render_to_pdf
from django.core.validators import ValidationError
def renderPDF(request):
    if request.GET:
        invoice_ID = request.GET.get('invoice_ID')
        if invoice_ID:
            result = SaleInvoice.objects.all().filter(invoice_ID=invoice_ID).values()
            df = pd.DataFrame(result)
            #theUser = User.objects.all().filter(id=(df['User_id'])).values('username')
            #df['total'].values
            data = {
                "title" : ' الفاتورة رقم {}'.format(invoice_ID),
                "invoice_ID" : invoice_ID,
                "customer_name" : df['customer_name'],
            }
            pdf = render_to_pdf('invoice.html', data)
            return HttpResponse(pdf, content_type='application/pdf')
        else:
            raise ValidationError
    else:
        return redirect('admin/')

Solution

  • I solved it, the docs have nothing wrong actually, the problem was in the static.. because when you use {% static 'whatever' %} it's going to search the static files but for some reason it didn't work I think the problem is from django itself, maybe you can't summon static from a pdf file. anywho this is my new invoice.html ( I've put the whole path to the font ):

    {% load static %}
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <head>
        
        <title>{{title}}</title>
        <style type="text/css">
            
    
            .header {
                font-size: 20px;
                font-weight: 100;
                text-align: center;
                color: #007cae;
            }
    
            .title {
                font-size: 22px;
                font-weight: 100;
                /* text-align: right;*/
                padding: 10px 20px 0px 20px;
            }
    
            .title span {
                color: #007cae;
            }
    
            .details {
                padding: 10px 20px 0px 20px;
                text-align: right !important;
                /*margin-left: 40%;*/
            }
    
            .hrItem {
                border: none;
                height: 1px;
                /* Set the hr color */
                color: #333;
                /* old IE */
                background-color: #fff;
                /* Modern Browsers */
            }
            @font-face {font-family: RTLFont; src: url('C:\\Users\\BigBoy\\Desktop\\MyProjects\\ToysSite\\static\\font\\Amiri-Italic.ttf')} // Here
            
            body {
                font-weight: 200;
                font-size: 14px;
                font-family: RTLFont;
            }
            /* @page {
            background-image: url('C:\Users\BigBoy\Desktop\MyProjects\ToysSite\static\background.png');
            } */
        </style>
    </head>
    
    <body>
        <div class='wrapper'>
            <div class='header'>
                
            </div>
            <div>
                <div class='details'>
                    <pdf:language name="arabic"/>
                    
                    اسم العميل : {{customer_name}} <br><hr>
                    <hr class='hrItem' />
                </div>
            </div>
        </div>
    </body>
    
    </html>