My favorite is lxml which includes a version of ElementTree as well as a really nice piece of code that they call "objectify". This latter piece will basically take XML and turn it into a dot notation Python object. I'll be using it to do our parsing because it is so straight-forward, easy to implement and understand. As stated earlier, I'll be using Reportlab to do the PDF creation piece.
Here's a simple script. that will do everything we need:
001.from decimal import Decimal
002.from lxml import etree, objectify
003.
004.from reportlab.lib import colors
005.from reportlab.lib.pagesizes import letter
006.from reportlab.lib.styles import getSampleStyleSheet
007.from reportlab.lib.units import inch, mm
008.from reportlab.pdfgen import canvas
009.from reportlab.platypus import Paragraph, Table, TableStyle
010.
011.########################################################################
012.class PDFOrder(object):
013.""""""
014.
015.#----------------------------------------------------------------------
016.def __init__(self, xml_file, pdf_file):
017."""Constructor"""
018.self.xml_file = xml_file
019.self.pdf_file = pdf_file
020.
021.self.xml_obj = self.getXMLObject()
022.
023.#----------------------------------------------------------------------
024.def coord(self, x, y, unit=1):
025."""
026.# http://stackoverflow.com/questions/4726011/wrap-text-in-a-table-reportlab
027.Helper class to help position flowables in Canvas objects
028."""
029.x, y = x * unit, self.height - y * unit
030.return x, y
031.
032.#----------------------------------------------------------------------
033.def createPDF(self):
034."""
035.Create a PDF based on the XML data
036."""
037.self.canvas = canvas.Canvas(self.pdf_file, pagesize=letter)
038.width, self.height = letter
039.styles = getSampleStyleSheet()
040.xml = self.xml_obj
041.
042.address = """
043.SHIP TO:
044.
045.
046.
047.%s
048.
049.%s
050.
051.%s
052.
053.%s
054.
055.
056.""" % (xml.address1, xml.address2, xml.address3, xml.address4)
057.p = Paragraph(address, styles["Normal"])
058.p.wrapOn(self.canvas, width, self.height)
059.p.drawOn(self.canvas, *self.coord(18, 40, mm))
060.
061.order_number = 'Order #%s ' %xml.order_number
062.p = Paragraph(order_number, styles["Normal"])
063.p.wrapOn(self.canvas, width, self.height)
064.p.drawOn(self.canvas, *self.coord(18, 50, mm))
065.
066.data = []
067.data.append(["Item ID", "Name", "Price", "Quantity", "Total"])
068.grand_total = 0
069.for item in xml.order_items.iterchildren():
070.row = []
071.row.append(item.id)
072.row.append(item.name)
073.row.append(item.price)
074.row.append(item.quantity)
075.total = Decimal(str(item.price)) * Decimal(str(item.quantity))
076.row.append(str(total))
077.grand_total += total
078.data.append(row)
079.data.append(["", "", "", "Grand Total:", grand_total])
080.t = Table(data, 1.5 * inch)
081.t.setStyle(TableStyle([
082.('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
083.('BOX', (0,0), (-1,-1), 0.25, colors.black)
084.]))
085.t.wrapOn(self.canvas, width, self.height)
086.t.drawOn(self.canvas, *self.coord(18, 85, mm))
087.
088.txt = "Thank you for your business!"
089.p = Paragraph(txt, styles["Normal"])
090.p.wrapOn(self.canvas, width, self.height)
091.p.drawOn(self.canvas, *self.coord(18, 95, mm))
092.
093.#----------------------------------------------------------------------
094.def getXMLObject(self):
095."""
096.Open the XML document and return an lxml XML document
097."""
098.with open(self.xml_file) as f:
099.xml = f.read()
100.return objectify.fromstring(xml)
101.
102.#----------------------------------------------------------------------
103.def savePDF(self):
104."""
105.Save the PDF to disk
106."""
107.self.canvas.save()
108.
109.#----------------------------------------------------------------------
110.if __name__ == "__main__":
111.xml = "order.xml"
112.pdf = "letter.pdf"
113.doc = PDFOrder(xml, pdf)
114.doc.createPDF()
115.doc.savePDF()
116.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/301743/viewspace-736309/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/301743/viewspace-736309/