Я хочу открыть PDF-файл для представлений Django, но в моем PDF-файле нет текста, а python возвращает мне пустой PDF-файл. На каждой странице это сканирование страницы: ссылка

from django.http import HttpResponse

def views_pdf(request, path):
   with open(path) as pdf:
   response = HttpResponse(pdf.read(),content_type='application/pdf')
   response['Content-Disposition'] = 'inline;elec'
   return response

Тип исключения: UnicodeDecodeError

Значение исключения: кодек charmap не может декодировать байт 0x9d в позиции 373: символы отображаются в

Подсказка об ошибке Юникода

Строка, которую не удалось закодировать / декодировать: ��`����

Как сказать в Python, что это не текст, а изображение?

0
Hyperion 17 Сен 2018 в 23:25

2 ответа

Лучший ответ

По умолчанию Python 3 открывает файлы в текстовом режиме , то есть пытается интерпретировать содержимое файла как текст. Это то, что вызывает исключение, которое вы видите.

Поскольку файл PDF (как правило) является двоичным файлом, попробуйте открыть файл в двоичном режиме. В этом случае read() вернет объект bytes.

Вот пример (в IPython). Сначала открываем как текст:

In [1]: with open('2377_001.pdf') as pdf:
   ...:     data = pdf.read()
   ...:     
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-1-d807b6ccea6e> in <module>()
      1 with open('2377_001.pdf') as pdf:
----> 2     data = pdf.read()
      3 

/usr/local/lib/python3.6/codecs.py in decode(self, input, final)
    319         # decode input (taking the buffer into account)
    320         data = self.buffer + input
--> 321         (result, consumed) = self._buffer_decode(data, self.errors, final)
    322         # keep undecoded input until the next call
    323         self.buffer = data[consumed:]

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

Далее читаем тот же файл в двоичном режиме:

In [2]: with open('2377_001.pdf', 'rb') as pdf:
   ...:     data = pdf.read()
   ...: 
In [3]: type(data)
Out[3]: bytes

In [4]: len(data)
Out[4]: 45659

In [5]: data[:10]
Out[5]: b'%PDF-1.4\n%'

Это решает первую часть, как читать данные.

Вторая часть - как передать его в HttpResponse. Согласно документации Django:

"Типичное использование - передача содержимого страницы в виде строки конструктору HttpResponse"

Таким образом, передача bytes может сработать, а может и не сработать (у меня не установлен Django для тестирования). В книге Django говорится:

"content должен быть итератором или строкой".

Я нашел следующую суть для записи двоичных данных:

from django.http import HttpResponse

def django_file_download_view(request):
    filepath = '/path/to/file.xlsx'
    with open(filepath, 'rb') as fp:  # Small fix to read as binary.
        data = fp.read()
    filename = 'some-filename.xlsx'
    response = HttpResponse(mimetype="application/ms-excel")
    response['Content-Disposition'] = 'attachment; filename=%s' % filename # force browser to download file
    response.write(data)
return response
0
Roland Smith 17 Сен 2018 в 20:48

Проблема, вероятно, в том, что файл, который вы пытаетесь использовать, использует неправильный тип кодировки. Вы можете легко найти кодировку своего PDF-файла в большинстве программ просмотра PDF-файлов, таких как Adobe Acrobat (в свойствах). Как только вы узнаете, какую кодировку он использует, вы можете передать ее Python следующим образом:

Замещать

with open(path) as pdf:

С :

with open(path, encoding="whatever encoding your pdf is in") as pdf:

Попробуйте кодировку Latin-1, это часто работает

0
Joseph Chotard 18 Сен 2018 в 00:40