如何使用Reportlab platypus(对齐段落)

时间:2016-04-20 13:21:10

标签: python pdf reportlab

我尝试使用reportlab和Playtipus模块从python创建PDF。

我希望pdf看起来像这样: Expected result

问题在于我不了解如何处理布局。 我创建了一个简单的PageTemplate,它是主页面,带有一个简单的Frame 但在这个简单的框架内,我需要一个可流动的"两个Colonne"布局。

页面模板:

class PageOne(PageTemplate):

def __init__(self, context):
    self.context = context
    self.largeur = self.context.doc.pagesize[0]
    self.hauteur = self.context.doc.pagesize[1]

    self.simpleFrame = Frame(self.context.doc.leftMargin, self.context.doc.bottomMargin, self.context.doc.width, self.context.doc.height - 3*cm, id='normal');
    PageTemplate.__init__(self, id="PageOne", frames=[self.simpleFrame], pagesize = A4, onPage = CommonReportPdf.footer_and_header)
    print("here 1 ")   

def beforeDrawPage(self, canvas, doc):
    canvas.saveState()
    try:
        print("beforeDrawPage")
    finally:
        canvas.restoreState()

自定义部分模型(表示具有相关测试的部分):

class CustomSection(Flowable):

def __init__(self, x=0, y=-15, width=80, height=15, title="", flowables=[]):
    Flowable.__init__(self)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.title = title
    self.styles = getSampleStyleSheet()        

def __repr__(self):
    return "CustomSection(w=%s)" % self.width

def _draw_title(self):
    print("draw title")
    self.canv.rect(self.x, self.y, self.width, self.height)
    self.canv.line(self.x, 0, 500, 0)

    p = Paragraph(self.title, style=self.styles["Normal"])
    p.wrapOn(self.canv, self.width, self.height)
    p.drawOn(self.canv, *self.coord(self.x+2, 10, mm))

def draw(self):
    self.canv.saveState()
    try:
        self._draw_title()
        # Here add SectionItemWithValue or SectionItemWithoutValue to this flowable
    finally:
        self.canv.restoreState()

def coord(self, x, y, unit=1):
    """
    http://stackoverflow.com/questions/4726011/wrap-text-in-a-table-reportlab
    Helper class to help position flowables in Canvas objects
    """
    x, y = x * unit, self.height - y * unit
    return x, y

流动性:

class SectionItemWithValue(Flowable):

    def __init__(self, title, result, value, x=0, y=-15, width=80, height=15):
        self.title = title
        self.result = result
        self.value = value

    def draw(self):
        self.canv.saveState()
        try:
            print("ok")
        finally:
            self.canv.restoreState()

class SectionItemWithoutValue(Flowable):

    def __init__(self, title, result, x=0, y=-15, width=80, height=15):
        self.title = title
        self.result = result

    def draw(self):
        self.canv.saveState()
        try:
            print("ok")
        finally:
            self.canv.restoreState()

Pdf生成类:

class XmlToPdf:

def __init__(self, xml_file):

    #self.root_xml = self.init_xml(xml_file)
    destination_path = "XmlToPdf.pdf"
    self.elements = []
    self.doc = BaseDocTemplate(destination_path, showBoundary=0, leftMargin=0.7 * cm, rightMargin=0.7*cm, topMargin=0.7*cm, bottomMargin=0.7*cm, pagesize=A4)
    self.simpleFrame = Frame(self.doc.leftMargin, self.doc.bottomMargin, self.doc.width, self.doc.height - 5*cm, id='normal')

def init_xml(self, xml_file):
    tree = ET.parse(xml_file)
    return tree.getroot()  

def create_pdf(self):
    styles = getSampleStyleSheet()

    _baseFontNameBI = tt2ps(_baseFontName, 1, 1)

    styles.add(ParagraphStyle(name='RightAlign', alignment=TA_RIGHT))
    styles.add(ParagraphStyle(name='LeftAlign', alignment=TA_LEFT))

    self.elements.append(Paragraph("Frame two columns,  "*2,styles['LeftAlign'])) #  I want both on the same line
    self.elements.append(Paragraph("Frame two columns,  "*2,styles['RightAlign'])) #  I want both on the same line
    self.elements.append(PageBreak())
    self.elements.append(Paragraph("Une colonne",styles['Normal']))
    self.elements.append(PageBreak())

    textWidth = stringWidth("Test title 1  ", _baseFontNameBI, 14)
    box = CustomSection(title="Contrôle logiciels", width=textWidth)
    self.elements.append(box)

    self.elements.append(Spacer(0, 20))

    self.elements.append(Paragraph("This is a paragraph", styles["Normal"]))

    textWidth = stringWidth("Test title 2", _baseFontNameBI, 14)        
    box = CustomSection(title="Test title 2", width=textWidth)
    self.elements.append(box)        
    self.elements.append(Spacer(0, 1*inch))

    textWidth = stringWidth("Test title 3", _baseFontNameBI, 14)
    box = CustomSection(title="Test title 3", width=textWidth)
    self.elements.append(box)        
    self.elements.append(Spacer(0, 1*inch))

    textWidth = stringWidth("Test title 4", _baseFontNameBI, 14)        
    box = CustomSection(title="Test title 5", width=textWidth)
    self.elements.append(box)        
    self.elements.append(Spacer(0, 1*inch))                        

    self.doc.totalPages = 4
    templates = [PageOne(self)]

    self.doc.addPageTemplates(templates)
    self.doc.build(self.elements)

我使用正确的组件?你有一些"复杂"文件例子?如何处理布局和段落?我应该用桌子吗?

0 个答案:

没有答案