I have generated a PDF file which contains Cyrillic characters (non-ASCII) with ReportLab. For this purpose I have used the "Montserrat" font, which support such characters. When I look in the generated PDF file inside the media folder of Django, the characters are correctly displayed:
I have embedded the font by using the following code in the function generating the PDF:
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('Montserrat', 'apps/Generic/static/Generic/tff/Montserrat-Regular.ttf'))
canvas_test = canvas.Canvas("media/"+filename, pagesize=A4)
canvas_test.setFont('Montserrat', 18)
canvas_test.drawString(10, 150, "Some text encoded in UTF-8")
canvas_test.drawString(10, 100, "как поживаешь")
canvas_test.save()
However, when I try to serve this PDF via HttpResponse, the Cyrillic characters are not properly displayed, despite being displayed in the Montserrat font:
The code that serves the PDF is the following:
# Return the pdf as a response
fs = FileSystemStorage()
if fs.exists(filename):
    with fs.open(filename) as pdf:
        response = HttpResponse(
            pdf, content_type='application/pdf; encoding=utf-8; charset=utf-8')
        response['Content-Disposition'] = 'inline; filename="'+filename+'"'
        return response
I have tried nearly everything (using FileResponse, opening the PDF with with open(fs.location + "/" + filename, 'rb') as pdf...) without success. Actually, I do not understand why, if ReportLab embeddes correctly the font (local file inside media folder), the file provided to the browser is not embedding the font.
It is also interesting to note that I have used Foxit Reader via Chrome or Edge to read the PDF. When I use the default PDF viewer of Firefox, different erroneous characters are displayed. Actually the font seems to be also erroneous in that case:
Edit
Thanks to @Melvyn, I have realized that the error did not lay in the response directly sent from the Python view, but in the success code in the AJAX call, which I leave hereafter:
$.ajax({
    method: "POST",
    url: window.location.href,
    data: { trigger: 'print_pdf', orientation: orientation, size: size},
    success: function (data) {
        if (data.error === undefined) {
            var blob = new Blob([data]);
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = filename + '.pdf';
            link.click();
        }
    }
 });
This is the part of the code that is changing somehow the encoding.
Solution with the ideas from comments
I finally come up with a solution thanks to all the comments I have received, specially from @Melvyn. Instead of creating a Blob object, I have just set the responseType of the AJAX to Blob type. This is possible since JQuery 3:
$.ajax({
    method: "POST",
    url: window.location.href,
    xhrFields:{
        responseType: 'blob'
    },
    data: { trigger: 'print_pdf', orientation: orientation, size: size},
    success: function (data) {
        if (data.error === undefined) {
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(data);
            link.download = filename + '.pdf';
            link.click();
        }
    }
 });
Handling an error when returning response
You can return an error from Python (i.e. catching an exception) as follows:
except Exception as err:
    response = JsonResponse({'msg': "Error"})
    error = err.args[0]
    if error is not None:
        response.status_code = 403 # To announce that the user isn't allowed to publish
        if error==13:
            error = "Access denied to the PDF file."
        response.reason_phrase = error
        return response
Then, you just have to use the native error handling from AJAX (after the success section):
error: function(data){
    $("#message_rows2").text(data.statusText);
    $('#errorPrinting').modal();
}
See further details in this link.
I hope this post helps people with the same problem while generating PDFs in non-ASCII (Cyrillic) characters. It took me several days...



 
    