Files
Fulfillment-Backend/barcodes/pdf/pdf_maker.py

84 lines
2.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from io import BytesIO
import fitz
import pdfrw
from fpdf import FPDF
class PdfMaker:
def __init__(self, size: tuple):
self.size = size
self.writer = pdfrw.PdfWriter()
def clear(self):
del self.writer
self.writer = pdfrw.PdfWriter()
def add_image(self, image_data):
size = self.size
fpdf = FPDF(format=size, unit="pt")
width, height = self.size
fpdf.add_page()
fpdf.image(image_data, 0, 0, width, height)
fpdf_reader: pdfrw.PdfReader = pdfrw.PdfReader(fdata=bytes(fpdf.output()))
self.writer.addpage(fpdf_reader.getPage(0))
def add_pdf(self, pdf_data: BytesIO):
pdf_reader = pdfrw.PdfReader(fdata=bytes(pdf_data.read()))
self.writer.addpage(pdf_reader.getPage(0))
def add_pdfs(self, pdf_data: BytesIO):
pdf_reader = pdfrw.PdfReader(fdata=bytes(pdf_data.read()))
self.writer.addpages(pdf_reader.readpages(pdf_reader.Root))
def get_bytes(self):
result_io = BytesIO()
self.writer.write(result_io)
result_io.seek(0)
return result_io
@staticmethod
def _get_target_rect(page: fitz.Page, target_ratio: float) -> fitz.Rect:
original_width, original_height = page.rect.width, page.rect.height
if original_width / original_height > target_ratio:
# Image is wider than target aspect ratio
new_width = original_width
new_height = int(original_width / target_ratio)
else:
# Image is taller than target aspect ratio
new_height = original_height
new_width = int(new_height * target_ratio)
return fitz.Rect(0, 0, new_width, new_height)
@staticmethod
def resize_pdf_with_reportlab(input_pdf_bytesio: BytesIO) -> BytesIO:
output_pdf = BytesIO()
pdf_document = fitz.open(stream=input_pdf_bytesio.getvalue(), filetype="pdf")
if len(pdf_document) != 1:
raise Exception("Ошибка. В документе должна быть одна страница.")
page = pdf_document[0]
target_ratio = 29 / 20
actual_ratio = page.rect.width / page.rect.height
if abs(actual_ratio - target_ratio) < 0.1:
return input_pdf_bytesio
rect = PdfMaker._get_target_rect(page, target_ratio)
page.set_mediabox(rect)
page.set_cropbox(rect)
page.set_bleedbox(rect)
page.set_trimbox(rect)
pdf_document.save(output_pdf)
pdf_document.close()
output_pdf.seek(0)
return output_pdf