10

I have a django app and I would like to create a pdf from my django view. I use weasyprint, and for some reason it doesn't accept my custom font. The font url is working and when I render the same html with the same font-face, I see the correct font, but my pdf is rendered with a wrong one. I also tried the base64 font string, but no luck. My render code is:

import os
from weasyprint import HTML, CSS
from weasyprint.fonts import FontConfiguration

from django.conf import settings
from django.http import HttpResponse
from django.template.loader import get_template
from django.urls import reverse


def render_to_pdf(template_src, context_dict={}):
    font_config = FontConfiguration()
    font_string = '''
        @font-face {
          font-family: 'Titillium Web';
          font-style: normal;
          font-weight: 300;
          src: local('Titillium Web Light'), local('TitilliumWeb-Light'), url('http://X.X.X.X:8000/static/fonts/titillium_web.woff2') format('woff2');
        }
        *, div {font-family: 'Titillium Web';}
    '''

    template = get_template(template_src)
    rendered_html  = template.render(context_dict)
    pdf_file = HTML(string=rendered_html).write_pdf(stylesheets=[
        CSS(settings.BASE_DIR +  '/gui/executive_summary.css'),
        CSS(string=font_string)],font_config=font_config)
    response = HttpResponse(pdf_file, content_type='application/pdf')
    response['Content-Disposition'] = 'filename="report.pdf"'
    return response

Any idea what am I doing wrong?

alexarsh
  • 5,123
  • 12
  • 42
  • 51

4 Answers4

6

there are two ways 1) upload font online and paste the link in url. eg : @font-face { font-family: Gentium; src: url(http://example.com/fonts/Gentium.otf); }

2) if you want to use font from local directory. eg :@font-face{ font-family: Gothan Narrow; src: url(file:///home/javed/Downloads/fonts/GothamNarrow-Light.otf) }

Javed Gouri
  • 289
  • 4
  • 5
  • Adding absolute path @font-face { font-family: kalpurush; src: url(file:///mnt/d/djangoprojects/dj-boot-modal/librarydb/static/librarydb/fonts/kalpurush.ttf); } solved my problem. – Lone Rider Jan 22 '21 at 15:42
5

As you can read in documentation:

WeasyPrint should support any font format handled by FreeType (any format widely used except WOFF2)

SRC: http://weasyprint.readthedocs.io/en/latest/features.html#fonts

MattSoft
  • 115
  • 1
  • 2
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/18240619) – yivi Dec 13 '17 at 11:50
  • 1
    i agree with @yivi a direct link is not really answering the question, and only the part that solve the problem should be included as an answer, not to mention that weasyprint documentation are not really providing exact solution for font problems – Ahmed Farahat May 22 '18 at 14:58
  • 2
    The source website seems to have changed and it no longer includes the exception regarding WOFF2. Nevertheless, WOFF2 still doesn't seem to work. Does anyone know whether it's supported now? – balu Jun 11 '20 at 18:35
  • `woff2_compress` is a tool that converts WOFF2 fonts into TrueType (`.ttf`) fonts. See https://github.com/google/woff2. You can then utilize a `src: url(file://path/to/truetype/yourfont.ttf)` line in your CSS. – Jerry Penner May 13 '21 at 22:57
2

If you have @font-face rules in your CSS, you have to create a FontConfiguration object:

fromweasyprintimport HTML, CSS
from weasyprint.fonts import FontConfiguration

font_config = FontConfiguration()
html = HTML(string='<h1>The title</h1>')
css = CSS(string='''
    @font-face {
        font-family: Gentium;
        src: url(http://example.com/fonts/Gentium.otf);
    }
    h1 { font-family: Gentium }''', font_config=font_config)
html.write_pdf(
    '/tmp/example.pdf', stylesheets=[stylesheet],
    font_config=font_config)

https://weasyprint.readthedocs.io/en/stable/tutorial.html?highlight=FontConfiguration

weaming
  • 5,605
  • 1
  • 23
  • 15
1

Working !!!

fromweasyprintimport HTML, CSS
from weasyprint.fonts import FontConfiguration

font_config = FontConfiguration()
html = HTML(string='<h1>The title</h1> html content here')

css = CSS(string='''            
      @font-face {
          font-family: 'TiroDevanagariMarathi';                
          src: url(../../static/fonts/TiroDevanagariMarathi-Regular.ttf) format('truetype');
          }
      h1 { font-family: TiroDevanagariMarathi }''', font_config=font_config)
    

html.write_pdf(
    '/my_file_path/example.pdf', stylesheets=[css],
    font_config=font_config)
Nids Barthwal
  • 2,205
  • 20
  • 12