ساخت فایل های pdf در جنگو
در این مقاله یاد میگیرید که چطور فایل های pdf را در جنگو ایجاد کنید. برای اینکار از یک پکیج قدرتمند به نام ReportLab استفاده می شود. با این پکیج میتوانید به شکل پویا فایل های pdf را برای اهداف مختلف ایجاد کنید.
دوره پیشنهادی: آموزش پیشرفته جنگو - ساخت فروشگاه اینترنتی
# نصب پکیج ReportLab
پکیج ReportLab در PyPI در دسترس است. میتوانید با دستور زیر این پکیج را نصب کنید:
python -m pip install reportlab
برای بررسی اینکه پکیج به دسترسی نصب شده است میتوانید در حالت تعاملی پایتون، ReportLab را وارد کنید:
>>> import reportlab
اگر خروجی این دستور خطایی نداشت، یعنی پکیج به درستی نصب شده است.
# ایجاد کردن فایل pdf در View جنگو
قبل از شروع باید دقت کنید که پکیج ReportLab با آبجکت های شبه فایل کار میکند و آبجکت FileResponse جنگو نیز این نوع آبجکت را می پذیرد. حالا مرحله به مرحله یک فایل pdf در جنگو ایجاد میکنیم.
ابتدا باید ماژول های مورد نیاز را import کنید:
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
ماژول io بخشی از کتابخانه استاندارد پایتون است و برای کار با داده های ورودی و خروجی حافظه است. کلاس بعدی FileResponse است که برای ارسال فایل به مرورگر کاربر استفاده می شود. یعنی اگر فایل pdf را بخواهید به کاربر ارسال کنید، می توانید از FileResponse استفاده کنید. در آخر، canvas را داریم که سطحی است که میتوان روی آن چیزی مثل متن، عکس، شکل و ... نوشت.
در مرحله بعد باید یک View جنگو ایجاد کنیم:
def some_view(request):
buffer = io.BytesIO()
در کد بالا یک view ایجاد کردیم. سپس یک بافر جدید از BytesIO ایجاد کردیم. برای ذخیره فایل های pdf میتوانیم مستقیم آن را روی هارد ذخیره کنیم اما در اینجا با استفاده از BytesIO فایل را در Ram ایجاد کردیم تا نیازی به ایجاد کردن فایل موقتی در سرور نباشد.
در مرحله بعد فایل pdf را می سازیم:
def some_view(request):
buffer = io.BytesIO()
p = canvas.Canvas(buffer) #new
p.drawString(100, 100, "Hello world.") #new
در اینجا یک فایل pdf ایجاد کردیم و به Canvas گفتیم که این فایل را در بافر ایجاد کند. سپس با دستور drawString یک متن را داخل این فایل نوشتیم. اعداد 100 هم نشان دهنده مختصات فایل است که میخواهیم در آن چیزی بنویسیم.
مرحله بعد به این شکل است:
def some_view(request):
buffer = io.BytesIO()
p = canvas.Canvas(buffer)
p.drawString(100, 100, "Hello world.")
p.showPage() #new
p.save() #new
دستور showPage مشخص می کند که این صفحه تمام شد و برو به صفحه بعد. مثلا اگر بخواهیم دو صفحه داشته باشیم، باید به شکل زیر کار کنیم:
p.drawString(100, 100, "Page 1")
p.showPage()
p.drawString(100, 100, "Page 2")
در آخر با دستور save ساخت فایل pdf را نهایی میکنیم و اطلاعات pdf را در buffer می نویسیم. تا قبل از دستور save ساخت pdf تکمیل نشده است.
ویدیو پیشنهادی: کار با فایل در پایتون
در مرحله آخر باید فایل را به کاربر برگردانید:
def some_view(request):
buffer = io.BytesIO()
p = canvas.Canvas(buffer)
p.drawString(100, 100, "Hello world.")
p.showPage()
p.save()
buffer.seek(0) #new
return FileResponse(buffer, as_attachment=True, filename="hello.pdf") #new
دستور seek بافر را به اول فایل برمیگرداند. این قسمت بسیار مهم است و یکی از چیزهایی است که در کار با فایلهای حافظهای باید به آن دقت کرد. وقتی اطلاعات داخل buffer نوشته می شود، مکان فعلی cursor در انتهای فایل قرار می گیرد. ولی ما میخواهیم که FileResponse فایل را از ابتدا بخواند.
در آخر، با استفاده از FileResponse فایل ایجاد شده را به کاربر ارسال میکنیم. در آرگومان ها، bugger همان فایل ساخته شده است. as_attachment مشخص میکند که مرورگر فایل را به عنوان یک فایل قابل دانلود ارائه کند. filename هم نام فایل دانلودی را مشخص میکند.