Есть ли способ использовать FPDF для генерации PDF-файла из форм в Django?
Я пытаюсь сгенерировать PDF файл и дать ему пользовательское имя, используя Django 4.0.2 У меня есть 2 входа, один для имени и один для фотографий, я хочу иметь возможность генерировать PDF без сохранения его в моей базе данных, но вернуть его обратно пользователю. Я не использую никаких моделей для этого, только html и python. У меня есть входные данные:
<input
type="text"
id="inputPassword6"
class="form-control"
aria-describedby="passwordHelpInline"
name="name"
/>
<input
class="form-control"
type="file"
id="formFileMultiple"
multiple
accept=".png, .jpeg, .jpg"
name="photos"
/>
<div class="d-grid gap-2 mt-3">
<button class="btn btn-success" type="submit">Save PDF</button>
</div>
Я пытаюсь объединить и вернуть PDF файл следующим образом:
if request.method == "POST" or "FILES":
name = request.POST["name"]
photos = request.FILES["photos"]
# Convert photos to PDF
pdf = FPDF()
# imagelist is the list with all image filenames
for image in photos:
pdf.add_page()
pdf.image(image, 0,0,210,297)
pdf.output(f"{name} AIA 114.pdf", "F")
Текущая ошибка:
Exception Type: TypeError
Exception Value:
argument should be integer or bytes-like object, not 'str'
Похоже, что FPDF не может просмотреть предоставленное мной изображение. Я попытался декодировать изображение, но столкнулся с другой ошибкой:
'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Может ли кто-нибудь помочь мне решить эту проблему или предложить другой способ ее решения?
Ниже приведено решение, которое сработало для меня при отсутствии моделей, однако оно жестко закодировано, поскольку позже я обнаружил, что мог бы использовать default_storage и ContentFile, встроенные в django, поскольку файлы уже находятся в памяти (InMemoryFile).
def index(request):
if request.method == "GET":
return render(request, 'index.html')
if request.method == "POST" or "FILES":
try:
# Get data from inputs
name = request.POST["name"]
photos = request.FILES.getlist('photos')
count = 1
if (len(photos) > 1):
# For multiple photos
imglist = []
counter = 0
# Write buffers and append to the list
for photo in photos:
bytes = photo.read() # Read files in memory
path = django_settings.MEDIA_ROOT + f"buffer{counter}.png" # auto path
counter = counter + 1 # counter
file = open(path, 'wb')
file.write(bytes)
file.close()
imglist.append(file)
# CONVERT
listconv = []
counter = 0
for img in imglist:
path = django_settings.MEDIA_ROOT + f"buffer{counter}.png"
img = Image.open(path)
img = img.convert('RGB')
listconv.append(img)
counter=counter+1
img.save(django_settings.MEDIA_ROOT + f"{name}.pdf", save_all=True, append_images=listconv[:-1])
# Return response
img = open(django_settings.MEDIA_ROOT + f"{name}.pdf", 'rb')
response = FileResponse(img)
return response
elif (len(photos) == 1):
# For single photo
photos = request.FILES["photos"]
# WRITE FILE
bytes = photos.read() # CONTENT UPLOADED FILE
path = django_settings.MEDIA_ROOT + "buffer"
file=open(path,'wb')
file.write(bytes)
file.close()
# CONVERT
image1 = Image.open(path)
im1 = image1.convert('RGB')
im1.save(django_settings.MEDIA_ROOT + f"{name}.pdf")
img = open(django_settings.MEDIA_ROOT + f"{name}.pdf", 'rb')
# Return response
response = FileResponse(img)
return response
else:
print("ERROR")
except UnidentifiedImageError:
return render(request, 'error.html')
return render(request, 'index.html')