121 lines
4.1 KiB
Python
121 lines
4.1 KiB
Python
|
# coding: utf-8
|
|||
|
|
|||
|
from decimal import Decimal
|
|||
|
from lxml import etree, objectify
|
|||
|
|
|||
|
from reportlab.lib import colors
|
|||
|
from reportlab.lib.pagesizes import letter
|
|||
|
from reportlab.lib.styles import getSampleStyleSheet
|
|||
|
from reportlab.lib.units import inch, mm
|
|||
|
from reportlab.pdfgen import canvas
|
|||
|
from reportlab.platypus import Paragraph, Table, TableStyle
|
|||
|
|
|||
|
from reportlab.pdfbase import pdfmetrics
|
|||
|
from reportlab.pdfbase.ttfonts import TTFont
|
|||
|
|
|||
|
|
|||
|
########################################################################
|
|||
|
class PDFOrder(object):
|
|||
|
""""""
|
|||
|
|
|||
|
# ----------------------------------------------------------------------
|
|||
|
def __init__(self, xml_file, pdf_file):
|
|||
|
"""Constructor"""
|
|||
|
self.xml_file = xml_file
|
|||
|
self.pdf_file = pdf_file
|
|||
|
|
|||
|
self.xml_obj = self.getXMLObject()
|
|||
|
|
|||
|
# ----------------------------------------------------------------------
|
|||
|
def coord(self, x, y, unit=1):
|
|||
|
"""
|
|||
|
# http://stackoverflow.com/questions/4726011/wrap-text-in-a-table-reportlab
|
|||
|
Вспомогательный класс для позиционирования в объектах Canvas
|
|||
|
"""
|
|||
|
x, y = x * unit, self.height - y * unit
|
|||
|
return x, y
|
|||
|
|
|||
|
# ----------------------------------------------------------------------
|
|||
|
def createPDF(self):
|
|||
|
"""
|
|||
|
Создаём PDF на основании XML данных
|
|||
|
"""
|
|||
|
self.canvas = canvas.Canvas(self.pdf_file, pagesize=letter)
|
|||
|
|
|||
|
pdfmetrics.registerFont(TTFont('FreeSans', 'FreeSans.ttf'))
|
|||
|
self.canvas.setFont('FreeSans', 32)
|
|||
|
|
|||
|
# self.canvas.setFont('Times-Roman', 20)
|
|||
|
width, self.height = letter
|
|||
|
styles = getSampleStyleSheet()
|
|||
|
xml = self.xml_obj
|
|||
|
|
|||
|
address = str(""" <font size="9">
|
|||
|
Доставка:<br/>
|
|||
|
ewdewfewfйцуцйу<br/>
|
|||
|
%s<br/>
|
|||
|
%s<br/>
|
|||
|
%s<br/>
|
|||
|
%s<br/>
|
|||
|
</font>
|
|||
|
""") % (xml.address1, xml.address2, xml.address3, xml.address4)
|
|||
|
p = Paragraph(address, styles["Normal"])
|
|||
|
|
|||
|
p.wrapOn(self.canvas, width, self.height)
|
|||
|
p.drawOn(self.canvas, *self.coord(18, 40, mm))
|
|||
|
|
|||
|
order_number = '<font size="14"><b>Order #%s </b></font>' % xml.order_number
|
|||
|
p = Paragraph(order_number, styles["Normal"])
|
|||
|
p.wrapOn(self.canvas, width, self.height)
|
|||
|
p.drawOn(self.canvas, *self.coord(18, 50, mm))
|
|||
|
|
|||
|
data = []
|
|||
|
data.append(["Item ID", "Name", "Price", "Quantity", "Total"])
|
|||
|
grand_total = 0
|
|||
|
for item in xml.order_items.iterchildren():
|
|||
|
row = []
|
|||
|
row.append(item.id)
|
|||
|
row.append(item.name)
|
|||
|
row.append(item.price)
|
|||
|
row.append(item.quantity)
|
|||
|
total = Decimal(str(item.price)) * Decimal(str(item.quantity))
|
|||
|
row.append(str(total))
|
|||
|
grand_total += total
|
|||
|
data.append(row)
|
|||
|
data.append(["", "", "", "Grand Total:", grand_total])
|
|||
|
t = Table(data, 1.5 * inch)
|
|||
|
t.setStyle(TableStyle([
|
|||
|
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
|
|||
|
('BOX', (0,0), (-1,-1), 0.25, colors.black)
|
|||
|
]))
|
|||
|
t.wrapOn(self.canvas, width, self.height)
|
|||
|
t.drawOn(self.canvas, *self.coord(18, 85, mm))
|
|||
|
|
|||
|
txt = "Thank you for your business!"
|
|||
|
p = Paragraph(txt, styles["Normal"])
|
|||
|
p.wrapOn(self.canvas, width, self.height)
|
|||
|
p.drawOn(self.canvas, *self.coord(18, 95, mm))
|
|||
|
|
|||
|
# ----------------------------------------------------------------------
|
|||
|
def getXMLObject(self):
|
|||
|
"""
|
|||
|
Открываем XML документ и возвращаем lxml XML документ
|
|||
|
"""
|
|||
|
with open(self.xml_file) as f:
|
|||
|
xml = f.read()
|
|||
|
return objectify.fromstring(xml)
|
|||
|
|
|||
|
#----------------------------------------------------------------------
|
|||
|
def savePDF(self):
|
|||
|
"""
|
|||
|
Сохраняем PDF
|
|||
|
"""
|
|||
|
self.canvas.save()
|
|||
|
|
|||
|
#----------------------------------------------------------------------
|
|||
|
if __name__ == "__main__":
|
|||
|
xml = "order.xml"
|
|||
|
pdf = "letter.pdf"
|
|||
|
doc = PDFOrder(xml, pdf)
|
|||
|
doc.createPDF()
|
|||
|
doc.savePDF()
|