121 lines
No EOL
4.1 KiB
Python
121 lines
No EOL
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() |