Django - сгенерированный в Пизе PDF-файл не содержит пробелов

Я использую Django, и мой код для рендеринга PDF действительно типичен:

t = loader.get_template('back/templates/content/receipt.html')
c = RequestContext(request, {
                             'pagesize': 'A4',
                             'invoice': invoice,
                             'plan': plan,
                             })

html = t.render(c)
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result)
if not pdf.err:
    return HttpResponse(result.getvalue(), mimetype="application/pdf")

И в квитанции.html нет ничего необычного:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Squizzal Receipt</title>
    <style type="text/css">
        @page {
            size: {{pagesize}};
            margin: 1cm;
            word-spacing 1cm;
            @frame footer {
                -pdf-frame-content: footerContent;
                bottom: 0cm;
                margin-left: 9cm;
                margin-right: 9cm;
                height: 1cm;
            }
        }
    </style>
</head>
<body>
    <h1>Your Receipt</h1>
   <<SNIP>>

но ни одно из пробелов в pdf не отображается. Все слова стоят рядом. Я пробовал обычные пробелы и " ", и результат тот же. Например, приведенное выше будет отображаться как «Ваша квитанция» в формате PDF.

Когда я пытаюсь использовать версию pisa для командной строки, она отлично генерирует PDF-файл с пробелами между словами.

Есть предположения?


person Mark    schedule 11.09.2011    source источник
comment
сохраните вывод HTML с помощью t.render(c).encode(UTF-8) в файл и передайте файл в версию командной строки. что он производит?   -  person akonsu    schedule 12.09.2011
comment
HTML-файл соответствует ожиданиям, и передача этого файла в строку cmd pisa дает ожидаемые результаты. На данный момент я тестирую это, используя сервер django dev, но я также тестировал его с помощью wsgi на apache. Я не могу думать ни о чем другом, что могло бы повлиять на это.   -  person Mark    schedule 12.09.2011
comment
попробуйте сохранить результат pisa.pisaDocument() в файл и открыть файл в программе просмотра PDF. Это нормально?   -  person akonsu    schedule 12.09.2011
comment
Так что я этого не понимаю. Если я это сделаю: pdf = pisa.CreatePDF(html.encode(UTF-8), file(test.pdf, wb)) он создаст хороший файл (с пробелами). Но когда я передаю ему объект результата StringIO и делаю: return HttpResponse(result.getvalue(), mimetype=application/pdf), пробелы удаляются. StringIO что-то делает с потоком?   -  person Mark    schedule 12.09.2011
comment
И pisaDocument, и CreatePDF дают одинаковые результаты. Я думаю, что это должно быть что-то со StringIO. Я также пробовал StringIO и cStringIO... те же результаты.   -  person Mark    schedule 12.09.2011
comment
чтобы проверить, что сохранить result.getvalue() в файл и просмотреть его. Я не знаю, что делает StringIO.   -  person akonsu    schedule 12.09.2011
comment
Сюжет сгущается. Запись result.getvalue() в файл создает PDF-файл с пробелами. Передача того же результата.getvalue() объекту Django HttpResponse удаляет пробелы. Я собираюсь посмотреть, есть ли лучший объект Django для использования с двоичными файлами.   -  person Mark    schedule 12.09.2011
comment
попробуйте result.seek(0) перед отправкой httpresponse и отправьте только результат в качестве первого параметра: HttpResponse(result, mimetype=application/pdf) (здесь я предполагаю, я понятия не имею, что не так)   -  person akonsu    schedule 12.09.2011
comment
Нет, все равно никакого эффекта. Мой ответ ниже показывает обходной путь, но я до сих пор понятия не понимаю, почему оригинальный способ не работает.   -  person Mark    schedule 12.09.2011


Ответы (2)


У меня была такая же проблема, и я не хотел принудительно загружать PDF-файл из браузера. Оказалось, что проблема связана с конкретной платформой: встроенный в Google Chrome плагин для просмотра PDF-файлов не отображает пробелы в определенных документах в определенных дистрибутивах Linux, если шрифты Microsoft TrueType не установлены. См. http://www.google.com/support/forum/p/Chrome/thread?tid=7169b114e8ea33c7&hl=en для получения подробной информации.

Я исправил это, просто выполнив следующие команды в bash (скорректируйте для своего дистрибутива; это было в Ubuntu):

$ sudo apt-get install msttcorefonts

(Примите лицензионное соглашение в процессе установки)

$ fc-cache -fv

После перезапуска Chrome (важно!), родной просмотрщик PDF корректно отображал PDF с пробелами.

person Alanyst    schedule 02.02.2012

Хорошо, спасибо akonsu, похоже, проблема заключается в том, как обрабатывается HttpResponse Django (либо на стороне сервера, либо на стороне браузера).

Вместо

 return HttpResponse(result.getvalue(), mimetype="application/pdf")

Использовать:

 resp = HttpResponse(result.getvalue(), mimetype="application/pdf")
 resp['Content-Disposition'] = 'attachment; filename=receipt.pdf'
 return resp

Это по крайней мере дает результат без пробелов. До сих пор не знаю, почему первый способ не работал.

person Mark    schedule 11.09.2011
comment
какого эффекта вы пытаетесь добиться? должен ли PDF-файл отображаться встроенным или браузер должен открывать диалоговое окно «Сохранить как» при переходе по URL-адресу? Кстати, вы установили заголовок длины содержимого? может из-за этого проблема? - person akonsu; 12.09.2011
comment
Ответ @Alanyst на самом деле правильный. Проблема не решена при принудительной загрузке файла, поскольку проблема заключается в том, что средство просмотра PDF-файлов Google Chrome не может правильно отображать PDF-файл. Установка расположения контента и принудительная загрузка просто обходят проблему. - person Owen Nelson; 22.06.2012
comment
@mark У меня все еще есть проблемы даже после использования вашего решения, какие-либо исправления? - person laycat; 16.07.2013