Форум сайта python.su
Сильно ну критикуйте, я новичек в программировании. Подскажите как сделать многостраничный PDF, в Гугле есть решения, для определенного текста, а у меня он парсится из XML
#!/usr/bin/python3 # -*- coding: utf-8 -*- from lxml import etree, objectify from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import inch, mm from reportlab.pdfgen.canvas import Canvas from reportlab.platypus import Paragraph, Table, TableStyle from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.lib import colors from reportlab.lib.pagesizes import letter pdfmetrics.registerFont(TTFont('FreeSans', 'FreeSans.ttf')) 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): x, y = x * unit, self.height - y * unit return x, y #---------------------------------------------------------------------- def createPDF(self): """ Создаём PDF на основании XML данных """ self.canvas = Canvas(self.pdf_file, pagesize=letter) width, self.height = letter styles = getSampleStyleSheet() xml = self.xml_obj order_number='<font name="FreeSans"><b>Отчет биллинговой системы</b></font>' p = Paragraph(order_number, styles["Normal"]) p.wrapOn(self.canvas, width, self.height) p.drawOn(self.canvas, *self.coord(18, 10, mm)) data = [] data.append(["Дата платежа", "Дата регистрации", "Адрес", "Лиц.счет", "Сумма", "Сборщик"]) for payment in xml.answer.findall('payment'): row = [] row.append(payment.get('payment_date')) row.append(payment.get('recieved_date')) row.append(payment.get('address')) row.append(payment.get('account')) row.append(payment.get('amount')) row.append(payment.get('collector')) data.append(row) data.append([]) t = Table(data) t.setStyle(TableStyle(( ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black), ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('TEXTCOLOR', (0, 0), (-1, -1), colors.blue), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, -1), 'FreeSans'), ('FONTSIZE', (0, 0), (-1, -1), 8) ))) t.wrapOn(self.canvas, width, self.height) t.drawOn(self.canvas, *self.coord(18, 385, mm)) #---------------------------------------------------------------------- def getXMLObject(self): """ Открываем XML документ и возвращаем lxml XML документ """ with open(self.xml_file) as f: xml = f.read() xml = bytes(bytearray(xml, encoding='utf-8')) return objectify.fromstring(xml) #---------------------------------------------------------------------- def savePDF(self): """ Сохраняем PDF """ self.canvas.save() #---------------------------------------------------------------------- if __name__ == "__main__": xml = "payments.xml" pdf = "letter2.pdf" doc = PDFOrder(xml, pdf) doc.createPDF() doc.savePDF()
Отредактировано Seman30 (Фев. 22, 2018 06:23:41)
Офлайн
Офлайн
FishHook
https://www.programcreek.com/python/example/60055/reportlab.platypus.PageBreak
Офлайн
Seman30Простите, 13 (!) примеров использования одной функции вам мало?
Было бы отлично, если бы сказали в какой части кода и какие строки добавить
Офлайн
FishHookОни однотипные на вид, я Python недавно изучаю и толком не понимаю еще нюансы. Хотелось бы получить помощь, т.к. программа не моя, я ее подгоняю под свои нужды. Впринципе уже все готово, надо только разделить на страницы, далее я все сам смогу
Отредактировано Seman30 (Фев. 22, 2018 09:06:34)
Офлайн
По логике надо после:
t.wrapOn(self.canvas, width, self.height)
t.drawOn(self.canvas, *self.coord(18, 385, mm))
Это:
data.append(PageBreak())
Запускается прога без ошибок, но разбиения нет
Офлайн
Seman30
Вы примеры запускать пробовали? Я не пробовал, мне это не надо, это же вам надо. Запустите пример, посмотрите как он работает, если такое поведение вас устраивает, переносите пример в ваш код, подстраивая его под ваши нужды. Если не устраивает, попробуйте разобраться в документации и понять, почему оно работает не так как вам нужно (возможно не хватает какого-то параметра функции или функция вообще не предусматривает нужное вам поведение) и в случае неудачи от вас вполне ожидаемо будет услышать следующий вопрос “Примеры посмотрел и потестировал, к сожалению, это не то поведение которое мне нужно”.
Отредактировано FishHook (Фев. 22, 2018 11:51:27)
Офлайн