Как написать код на Python, который объединяет 2 файла, созданные с помощью wkhtmltopdf, в 1 pdf файл с помощью pypdf2
У меня есть приложение с бэкендом, написанным на Python, которое конвертирует html файлы в pdf файлы. Для этого оно реализует wkhtmltopdf (https://wkhtmltopdf.org/). В настоящее время он прекрасно работает для создания одного PDF файла из html файла и вывода его пользователю.
Однако мне нужно иметь возможность создавать несколько раздельных PDF файлов, а затем объединять их в один PDF.
Я пытался сделать это с помощью Pypdf2 с функцией PdfFileMerger() (https://pythonhosted.org/PyPDF2/PdfFileMerger.html) и не смог этого сделать. Я продолжаю получать 'bytes' object has no attribute 'seek'
Вот мой текущий код:
def multi_test_sheet(request, equipment_id):
if not request.user.is_authenticated:
return render(request, "jobs/login.html", {"message": None})
from io import BytesIO
from PyPDF2 import PdfFileReader, PdfFileMerger
if not request.user.is_authenticated:
return render(request, "jobs/login.html", {"message": None})
equipment = Equipment.objects.filter(pk=equipment_id).first()
if not job:
raise Http404("test sheet error. Error code: get job failed")
pdf_write = PdfFileWriter()
user_properties=UserProperties.objects.get(user=request.user)
context = {
"equipment": equipment,
"job": equipment.equipments,
"test_sheet": equipment.sheet_eq,
"user_properties": user_properties,
"now": datetime.now().strftime("%b-%d-%Y %H:%M"),
"now_date": datetime.now().date()
}
html_sheet = render_to_string('jobs/test_sheet_gear1.html', context)
html_sheet2 = render_to_string('jobs/test_sheet_gear2.html', context)
pdf_content1 = pdfkit.from_string(html_sheet, None)
pdf_content2 = pdfkit.from_string(html_sheet2, None)
pdfadder = PdfFileMerger(strict=False)
pdfadder.append(pdf_content1)
pdfadder.append(pdf_content2)
pdf_adder.write("combined_sheets.pdf")
response = HttpResponse(pdf_adder, content_type="application/pdf")
response["Content-Disposition"] = f"filename={equipment.site_id}.pdf"
return response
Я решил эту проблему, наняв человека. Проблема заключалась в том, что объекты, передаваемые в функцию PyPDF2 под названием PdfFileMerger(), не распознавались как объекты pdf.
Чтобы решить эту проблему, сохраните файлы (я помещаю их в папку под названием interim), используя второй аргумент функции pdfkit.from_string(), затем присвойте вновь созданные файлы независимым переменным, используя функцию open(), и, наконец, перейдите к функции объединения, объединив эти переменные.
def multi_test_sheet(request, equipment_id):
if not request.user.is_authenticated:
return render(request, "jobs/login.html", {"message": None})
from io import BytesIO
from PyPDF2 import PdfFileReader, PdfFileMerger
if not request.user.is_authenticated:
return render(request, "jobs/login.html", {"message": None})
equipment = Equipment.objects.filter(pk=equipment_id).first()
if not job:
raise Http404("test sheet error. Error code: get job failed")
page_quantity = 2 #temporary value for a property that will be added to either equipment or test sheet model
pdf_file_object = BytesIO()
stream = BytesIO()
pdf_write = PdfFileWriter()
user_properties=UserProperties.objects.get(user=request.user)
today = datetime.now()
now=today.strftime("%b-%d-%Y %H:%M")
now_date = today.date()
context = {
"equipment": equipment,
"job": equipment.equipments,
"test_sheet": equipment.sheet_eq,
"user_properties": user_properties,
"now": now,
"now_date": now_date
}
html_sheet = render_to_string('jobs/test_sheet_gear1.html', context)
html_sheet2 = render_to_string('jobs/test_sheet_gear2.html', context)
pdf_content1 = pdfkit.from_string(html_sheet, 'interm/test_sheet_gear1.pdf')
pdf_content2 = pdfkit.from_string(html_sheet2, 'interm/test_sheet_gear2.pdf')
pdfadder = PdfFileMerger(strict=False)
pdf1_v=PdfFileReader(open('interm/test_sheet_gear1.pdf', 'rb'))
pdf2_v=PdfFileReader(open('interm/test_sheet_gear2.pdf', 'rb'))
pdfadder.append(pdf1_v, import_bookmarks=False)
pdfadder.append(pdf2_v, import_bookmarks=False)
pdfadder.write('interm/'+str(user_properties.pk)+'combined_sheets.pdf')
output_file = open('interm/combined_sheets.pdf', 'rb')
response = HttpResponse(output_file, content_type="application/pdf")
response["Content-Disposition"] = f"filename={equipment.site_id}.pdf"
return response