وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

ایجاد فاکتورهای PDF در پایتون با borb

0 34
زمان لازم برای مطالعه: 7 دقیقه


معرفی

این فرمت سند قابل حمل (PDF) فرمت WYSIWYG (آنچه می بینید همان چیزی است که می گیرید) نیست. این برای پلتفرم-آگنوستیک، مستقل از سیستم عامل اصلی و موتورهای رندر توسعه داده شد.

برای دستیابی به این هدف، PDF ساخته شد تا از طریق چیزی بیشتر شبیه به یک زبان برنامه نویسی و متکی با آن تعامل داشته باشد. روی مجموعه ای از دستورالعمل ها و عملیات برای رسیدن به نتیجه. در واقع PDF است مستقر روی یک زبان برنامه نویسی – پست اسکریپتکه اولین دستگاه مستقل بود زبان توضیحات صفحه.

در این راهنما، ما استفاده خواهیم کرد بورب – یک کتابخانه پایتون که به خواندن، دستکاری و تولید اسناد PDF اختصاص یافته است. هم یک مدل سطح پایین (که به شما امکان می‌دهد به مختصات و طرح‌بندی دقیق در صورت استفاده از آن‌ها دسترسی داشته باشید) و هم یک مدل سطح بالا (که در آن می‌توانید محاسبات دقیق حاشیه‌ها، موقعیت‌ها و غیره را به یک مدیر طرح‌بندی واگذار کنید) ارائه می‌دهد. .

ما نگاهی به روش ایجاد فاکتور PDF در پایتون با استفاده از borb.

نصب borb

بورب را می توان از منبع دانلود کرد روی GitHub، یا نصب شده از طریق pip:

$ pip install borb

ایجاد فاکتور PDF در پایتون با borb

بورب دارای دو کلاس کلیدی بصری – Document و Page، که نشان دهنده یک سند و صفحات درون آن است. علاوه بر این، PDF کلاس یک API را برای بارگیری و ذخیره کردن نشان می دهد Documentما ایجاد می کنیم.

بیایید یک را ایجاد کنیم Document() و Page() به عنوان یک بوم خالی که می توانیم فاکتور را به آن اضافه کنیم:

from borb.pdf.document import Document
from borb.pdf.page.page import Page


pdf = Document()


page = Page()
pdf.append_page(page)

از آنجایی که ما نمی خواهیم با محاسبه مختصات سر و کار داشته باشیم – می توانیم این را به a واگذار کنیم PageLayout که تمام محتوا و موقعیت های آن را مدیریت می کند:


from borb.pdf.canvas.layout.page_layout.multi_column_layout import SingleColumnLayout
from decimal import Decimal

page_layout = SingleColumnLayout(page)
page_layout.vertical_margin = page.get_page_info().get_height() * Decimal(0.02)

در اینجا، ما از a استفاده می کنیم SingleColumnLayout از آنجایی که همه محتوا باید در یک ستون باشد – ما سمت چپ و راست فاکتور نخواهیم داشت. ما همچنین حاشیه عمودی را در اینجا کوچکتر می کنیم. مقدار پیش‌فرض این است که 10 درصد بالا را برش دهید page ارتفاع به عنوان حاشیه، و ما آن را به 2٪ کاهش می دهیم، زیرا می خواهیم از این فضا برای نشان و نام شرکت استفاده کنیم.

در مورد آن، بیایید لوگوی شرکت را به طرح اضافه کنیم:


from borb.pdf.canvas.layout.image.image import Image


page_layout.add(    
        Image(        
        "https://s3.rasanegar.com/media/articles/creating-an-invoice-in-python-with-ptext-1.png",        
        width=Decimal(128),        
        height=Decimal(128),    
        ))

در اینجا، ما یک عنصر را به طرح اضافه می کنیم – an Image(). از طریق سازنده آن، یک URL اضافه می کنیم که به منبع تصویر اشاره می کند و آن را تنظیم می کنیم width و height.

در زیر تصویر، ما می خواهیم اطلاعات خیالی شرکت (نام، آدرس، وب سایت، تلفن) و همچنین اطلاعات فاکتور (شماره فاکتور، تاریخ، تاریخ سررسید) را اضافه کنیم. یک فرمت رایج برای مختصر (که اتفاقاً کد را نیز پاک‌تر می‌کند) استفاده از a است جدول برای ذخیره داده های فاکتور بیایید یک روش کمکی جداگانه برای ساخت اطلاعات فاکتور در یک جدول ایجاد کنیم، که سپس می‌توانیم از آن برای اضافه کردن یک جدول به صورت حساب در روش اصلی خود استفاده کنیم:


from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable as Table
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.layout.layout_element import Alignment
from datetime import datetime
import random

def _build_invoice_information():    
    table_001 = Table(number_of_rows=5, number_of_columns=3)
    
    table_001.add(Paragraph("(Street Address)"))    
    table_001.add(Paragraph("Date", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT))    
    now = datetime.now()    
    table_001.add(Paragraph("%d/%d/%d" % (now.day, now.month, now.year)))
    
    table_001.add(Paragraph("(City, State, ZIP Code)"))    
    table_001.add(Paragraph("Invoice #", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT))
    table_001.add(Paragraph("%d" % random.randint(1000, 10000)))   
    
    table_001.add(Paragraph("(Phone)"))    
    table_001.add(Paragraph("Due Date", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT))
    table_001.add(Paragraph("%d/%d/%d" % (now.day, now.month, now.year))) 
    
    table_001.add(Paragraph("(Email Address)"))    
    table_001.add(Paragraph(" "))
    table_001.add(Paragraph(" "))

    table_001.add(Paragraph("(Company Website)"))
    table_001.add(Paragraph(" "))
    table_001.add(Paragraph(" "))

    table_001.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))    		
    table_001.no_borders()
    return table_001

در اینجا، ما در حال ساخت یک ساده هستیم Table دارای 5 سطر و 3 ستون ردیف ها با آدرس خیابان، شهر/ایالت، تلفن، آدرس ایمیل و وب سایت شرکت مطابقت دارند. هر ردیف خواهد داشت 0..3 مقادیر (ستون ها). هر عنصر متن به عنوان یک اضافه می شود Paragraph، که از طریق آن را به سمت راست تراز کرده ایم Alignment.RIGHT، و استدلال های سبک مانند را بپذیرید font.

در نهایت، ما به تمام سلول‌ها padding اضافه کرده‌ایم تا مطمئن شویم که متن را به‌طور نامناسبی در نزدیکی سلول‌ها قرار نمی‌دهیم.

اکنون، به روش اصلی خود، می توانیم تماس بگیریم _build_invoice_information() برای پر کردن جدول و اضافه کردن آن به طرح‌بندی:

page_layout = SingleColumnLayout(page)
page_layout.vertical_margin = page.get_page_info().get_height() * Decimal(0.02)
page_layout.add(    
    Image(        
        "https://s3.rasanegar.com/media/articles/creating-an-invoice-in-python-with-ptext-1.png",        
        width=Decimal(128),        
        height=Decimal(128),    
        ))


page_layout.add(_build_invoice_information())  
  

page_layout.add(Paragraph(" "))

اکنون، بیایید این سند PDF را به سرعت بسازیم تا ببینیم چگونه به نظر می رسد. برای این کار از PDF مدول:


from borb.pdf.pdf import PDF

with open("output.pdf", "wb") as pdf_file_handle:
    PDF.dumps(pdf_file_handle, pdf)

فاکتور borb 1

عالی! اکنون می خواهیم اطلاعات صورتحساب و حمل و نقل را نیز اضافه کنیم. درست مانند اطلاعات شرکت، به راحتی در یک جدول قرار می گیرد. برای اختصار، ما همچنین تصمیم می گیریم که یک تابع کمکی جداگانه برای ساخت این اطلاعات ایجاد کنیم، و سپس می توانیم به سادگی آن را در روش اصلی خود اضافه کنیم:


from borb.pdf.canvas.color.color import HexColor, X11Color

def _build_billing_and_shipping_information():  
    table_001 = Table(number_of_rows=6, number_of_columns=2)  
    table_001.add(  
        Paragraph(  
            "BILL TO",  
            background_color=HexColor("263238"),  
            font_color=X11Color("White"),  
        )  
    )  
    table_001.add(  
        Paragraph(  
            "SHIP TO",  
            background_color=HexColor("263238"),  
            font_color=X11Color("White"),  
        )  
    )  
    table_001.add(Paragraph("(Recipient Name)"))        
    table_001.add(Paragraph("(Recipient Name)"))        
    table_001.add(Paragraph("(Company Name)"))          
    table_001.add(Paragraph("(Company Name)"))          
    table_001.add(Paragraph("(Street Address)"))        
    table_001.add(Paragraph("(Street Address)"))        
    table_001.add(Paragraph("(City, State, ZIP Code)")) 
    table_001.add(Paragraph("(City, State, ZIP Code)")) 
    table_001.add(Paragraph("(Phone)"))                 
    table_001.add(Paragraph("(Phone)"))                 
    table_001.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))  
    table_001.no_borders()  
    return table_001

ما تنظیم کرده ایم background_color از پاراگراف های اولیه به #263238 (خاکستری-آبی) برای مطابقت با رنگ لوگو، و font_color به White.

بیایید این را در روش اصلی نیز صدا کنیم:


page_layout.add(_build_invoice_information())


page_layout.add(Paragraph(" "))


page_layout.add(_build_billing_and_shipping_information())

هنگامی که اسکریپت را دوباره اجرا می کنیم، یک فایل PDF جدید ایجاد می شود که حاوی اطلاعات بیشتری است:

فاکتور borb 2

با طبقه بندی اطلاعات اولیه ما (اطلاعات شرکت و اطلاعات صورتحساب/ حمل و نقل) – می خواهیم یک توضیح جزئی اضافه کنیم. اینها کالاها/خدماتی خواهند بود که شرکت فرضی ما به شخصی ارائه کرده است و همچنین معمولاً به شکل جدولی زیر اطلاعاتی که قبلاً اضافه کرده ایم انجام می شود.

دوباره، بیایید یک تابع کمکی ایجاد کنیم که یک جدول تولید می کند و آن را با داده ها پر می کند، که بعداً می توانیم به سادگی به طرح بندی خود اضافه کنیم. روی:


from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable as Table
from borb.pdf.canvas.layout.table.table import TableCell


def _build_itemized_description_table(self):  
    table_001 = Table(number_of_rows=15, number_of_columns=4)  
    for h in ("DESCRIPTION", "QTY", "UNIT PRICE", "AMOUNT"):  
        table_001.add(  
            TableCell(  
                Paragraph(h, font_color=X11Color("White")),  
                background_color=HexColor("016934"),  
            )  
        )  
  
    odd_color = HexColor("BBBBBB")  
    even_color = HexColor("FFFFFF")  
    for row_number, item in enumerate((("Product 1", 2, 50), ("Product 2", 4, 60), ("Labor", 14, 60))):  
        c = even_color if row_number % 2 == 0 else odd_color  
        table_001.add(TableCell(Paragraph(item(0)), background_color=c))  
        table_001.add(TableCell(Paragraph(str(item(1))), background_color=c))  
        table_001.add(TableCell(Paragraph("$ " + str(item(2))), background_color=c))  
        table_001.add(TableCell(Paragraph("$ " + str(item(1) * item(2))), background_color=c))  
      
    
    for row_number in range(3, 10):  
        c = even_color if row_number % 2 == 0 else odd_color  
        for _ in range(0, 4):  
            table_001.add(TableCell(Paragraph(" "), background_color=c))  
  
    table_001.add(TableCell(Paragraph("Subtotal", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT,), col_span=3,))  
    table_001.add(TableCell(Paragraph("$ 1,180.00", horizontal_alignment=Alignment.RIGHT)))  
    table_001.add(TableCell(Paragraph("Discounts", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT,),col_span=3,))  
    table_001.add(TableCell(Paragraph("$ 177.00", horizontal_alignment=Alignment.RIGHT)))  
    table_001.add(TableCell(Paragraph("Taxes", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT), col_span=3,))  
    table_001.add(TableCell(Paragraph("$ 100.30", horizontal_alignment=Alignment.RIGHT)))  
    table_001.add(TableCell(Paragraph("Total", font="Helvetica-Bold", horizontal_alignment=Alignment.RIGHT  ), col_span=3,))  
    table_001.add(TableCell(Paragraph("$ 1163.30", horizontal_alignment=Alignment.RIGHT)))  
    table_001.set_padding_on_all_cells(Decimal(2), Decimal(2), Decimal(2), Decimal(2))  
    table_001.no_borders()  
    return table_001

در عمل، رشته‌های رمزگذاری‌شده مربوط به کل فرعی، مالیات‌ها و قیمت‌های کل را با محاسبات قیمت‌های واقعی جایگزین می‌کنید – هرچند، این به شدت بستگی دارد. روی اجرای اساسی شما Product مدل ها ، بنابراین ما یک ایستاده برای انتزاع اضافه کرده ایم. پس از اضافه کردن این جدول به سند – می توانیم آن را دوباره بسازیم و نگاهی بیندازیم.

اکنون کل روش اصلی باید چیزی در امتداد خطوط زیر باشد:


pdf = Document()


page = Page()
pdf.append_page(page)

page_layout = SingleColumnLayout(page)
page_layout.vertical_margin = page.get_page_info().get_height() * Decimal(0.02)

page_layout.add(
        Image(
        "https://s3.rasanegar.com/media/articles/creating-an-invoice-in-python-with-ptext-1.png",
        width=Decimal(128),
        height=Decimal(128),
        ))



page_layout.add(_build_invoice_information())


page_layout.add(Paragraph(" "))


page_layout.add(_build_billing_and_shipping_information())


page_layout.add(_build_itemized_description_table())

with open("output2.pdf", "wb") as pdf_file_handle:
    PDF.dumps(pdf_file_handle, pdf)

اجرای این قطعه کد به این نتیجه می رسد:

فاکتور borb 3

ایجاد طرح کلی

PDF ما انجام شده و آماده سرو است – هرچند ، ما می توانیم آن را با دو مورد کوچک اضافه کنیم. ابتدا می توانیم یک عدد اضافه کنیم طرح کلی، که به خوانندگانی مانند Adobe کمک می کند تا در PDF های شما منویی تولید کنند و تولید کنند:


from borb.pdf.page.page import DestinationType


pdf.add_outline("Your Invoice", 0, DestinationType.FIT, page_nr=0)

این add_outline() تابع چند آرگومان را می پذیرد:

  • title : عنوانی که در منوی جانبی نمایش داده می شود
  • level : چه چیزی در اعماق درخت خواهد بود. سطح 0 است root-مرحله.
  • چندین استدلال که یک “مقصد” را تشکیل می دهند

مقصد را می توان به عنوان اهداف لینک لینک فکر کرد. می توانید به یک کل پیوند دهید page (این همان کاری است که ما در این مثال انجام می دهیم) ، اما شما همچنین می توانید به قسمت های خاصی از a پیوند دهید page (به عنوان مثال – دقیقاً در مختصات y 350).

علاوه بر این ، شما باید مشخص کنید که چگونه خواننده باید آن را ارائه دهد page – به عنوان مثال ، آیا می خواهید به سادگی به آن پیمایش کنید page و زوم نکنیم؟ آیا می‌خواهید فقط یک ناحیه مورد نظر را نمایش دهید، در حالی که خواننده به طور کامل در آن منطقه خاص زوم شده است؟

در این خط کد ، ما از خواننده می خواهیم که نمایش دهد page 0 (اولین page) و مطمئن شوید که با پنجره خواننده مطابقت دارد (در صورت نیاز بزرگنمایی/کوچک کردن).

پس از افزودن طرح کلی ، باید آن را در خواننده مورد نظر خود مشاهده کنید:

فاکتور borb 4

با چندین صفحه – می توانید طرح کلی پیچیده تری ایجاد کنید و از طریق آنها به آنها پیوند دهید add_outline() برای ناوبری راحت تر

جاسازی اسناد JSON در فاکتورهای PDF

از آنجایی که PDF ها (از نظر خواندن و رمزگشایی بدون ابهام) بسیار سازگار با کامپیوتر نیستند – گاهی اوقات، ممکن است بخواهیم فرمت های سازگار با کامپیوتر بیشتری را نیز اضافه کنیم. process فاکتورها به صورت خودکار

یک استاندارد فاکتور آلمانی به نام ZUGFeRD (که بعداً توسط اتحادیه اروپا تصویب شد) ما را قادر می سازد فاکتورهای PDF را با فرمت های فایل خوانا در رایانه مانند XML ایجاد کنیم – که فاکتور را توصیف می کند و به راحتی قابل تجزیه است. علاوه بر اینها، می توانید سایر اسناد مربوط به فاکتور خود مانند شرایط و توافقات، سیاست بازپرداخت و غیره را نیز درج کنید.

برای جاسازی هر نوع فایل اضافی در یک فایل PDF، با استفاده از borb – می توانیم از آن استفاده کنیم append_embedded_file() تابع.

بیایید ابتدا پیش برویم و یک فرهنگ لغت ایجاد کنیم تا داده‌های فاکتور خود را در JSON ذخیره کنیم، که سپس آن را در یک فایل ذخیره می‌کنیم. invoice_json فایل:

import json


invoice_json = {  
"items": (  
    {  
        "Description": "Product1",  
        "Quantity": 2,  
        "Unit Price": 50,  
        "Amount": 100,  
    },  
    {  
        "Description": "Product2",  
        "Quantity": 4,  
        "Unit Price": 60,  
        "Amount": 100,  
    },  
    {  
        "Description": "Labor",  
        "Quantity": 14,  
        "Unit Price": 60,  
        "Amount": 100,  
    },  
),  
"Subtotal": 1180,  
"Discounts": 177,  
"Taxes": 100.30,  
"Total": 1163.30,  
}  
invoice_json_bytes = bytes(json.dumps(invoice_json, indent=4), encoding="latin1")

اکنون، ما می توانیم به سادگی این فایل را در فاکتور PDF خود جاسازی کنیم:

pdf.append_embedded_file("invoice.json", invoice_json_bytes)

هنگامی که اسکریپت را دوباره اجرا می کنیم و سند را ذخیره می کنیم، می رویم:

فاکتور borb 5

نتیجه

در این راهنما، نگاهی به روش ایجاد فاکتور در پایتون با استفاده از borb انداخته ایم. سپس برای سهولت پیمایش، طرح کلی را به فایل PDF اضافه کرده‌ایم و نگاهی به روش افزودن پیوست‌ها/فایل‌های تعبیه‌شده برای دسترسی برنامه‌ای به محتویات PDF انداخته‌ایم.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-10 22:03:05

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید