Changeset 804

Show
Ignore:
Timestamp:
02/16/05 23:03:33 (4 years ago)
Author:
paul
Message:

Refactoring: now most props are expressions that are evaluated at runtime
for very dynamic report writing. Fixed rotation of text objects.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/reporting/reportWriter.py

    r799 r804  
    55##  test.pdf file. 
    66 
     7##  Almost all values from the spec file are evaluated at runtime, allowing 
     8##  simple yet flexible redirection (a given prop can be gotten at runtime 
     9##  from a user-defined function). 
     10 
    711import sys 
    8 from reportlab.pdfgen.canvas import Canvas 
     12import reportlab.pdfgen.canvas as canvas 
     13import reportlab.graphics.shapes as shapes 
    914import reportlab.lib.pagesizes as pagesizes 
     15import reportlab.lib.units as units 
     16#import reportlab.lib.colors as colors 
    1017 
    1118#form = sys.argv[1] 
    1219import samplespec as form 
     20 
    1321 
    1422#data = sys.argv[2] 
     
    2028showBands = True 
    2129 
    22 unit = form.Page["unit"] 
    23 if unit == "inch": 
    24     u = 72 
    25  
    26 if form.Page["size"] == "letter": 
     30 
     31pageSize = eval(form.Page["size"]) 
     32if pageSize == "letter": 
    2733    pageSize = pagesizes.letter 
    28 elif form.Page["size"] == "a4": 
     34elif pageSize == "a4": 
    2935    pageSize = pagesizes.a4 
    3036 
    31 c = Canvas("test.pdf", pagesize=pageSize) 
     37 
     38c = canvas.Canvas("test.pdf", pagesize=pageSize) 
    3239pageWidth, pageHeight = pageSize 
    3340 
    3441print "pageWidth, pageHeight:", pageWidth, pageHeight 
    3542 
    36 pageHeaderOrigin = (u*form.Page["margin"]["left"], 
    37                    pageHeight - (u*form.Page["margin"]["top"]) 
    38                               - (u*form.PageHeader["height"])) 
    39 pageHeaderDestination = (pageWidth - (u*form.Page["margin"]["right"]), 
    40                    pageHeight - (u*form.Page["margin"]["top"])) 
    41  
    42 print "pageHeaderOrigin, pageHeaderDestination:", pageHeaderOrigin, pageHeaderDestination 
    43  
    44 pageFooterOrigin = (u*form.Page["margin"]["left"],  
    45                     u*form.Page["margin"]["bottom"]) 
    46 pageFooterDestination = (pageWidth - (u*form.Page["margin"]["right"]), 
    47                     u*(form.PageFooter["height"] + form.Page["margin"]["bottom"])) 
    48  
    49 print "pageFooterOrigin, pageFooterDestination:", pageFooterOrigin, pageFooterDestination 
    50  
    51 ml = u*form.Page["margin"]["left"] 
    52 mt = u*form.Page["margin"]["top"] 
    53 mr = u*form.Page["margin"]["right"] 
    54 mb = u*form.Page["margin"]["bottom"] 
    55  
     43 
     44ml = units.toLength(eval(form.Page["margin"]["left"])) 
     45mt = units.toLength(eval(form.Page["margin"]["top"])) 
     46mr = units.toLength(eval(form.Page["margin"]["right"])) 
     47mb = units.toLength(eval(form.Page["margin"]["bottom"])) 
     48 
     49pageHeaderOrigin = (ml, pageHeight - mt  
     50                    - units.toLength(eval(form.PageHeader["height"]))) 
     51pageFooterOrigin = (ml, mb) 
    5652 
    5753def printBandOutline(band, x, y, width, height): 
     
    6864 
    6965def draw(object, x, y): 
    70      
    7166    c.saveState() 
    7267 
    73     try: width = (u*object["width"]) 
    74     except (KeyError, TypeError): width = None 
    75  
    76     try: height = (u*object["height"]) 
    77     except (KeyError, TypeError): height = None 
    78  
    79     try: rotation = object["rotation"] 
    80     except KeyError:    rotation = 0 
    81  
    82     c.rotate(rotation) 
    83  
    84     if object["type"] == "rectangle": 
    85         try: lineWidth = object["lineWidth"] 
    86         except KeyError: lineWidth = 1 
    87         c.setLineWidth(lineWidth) 
    88         c.rect(x,y,width,height) 
     68    try:  
     69        width = units.toLength(eval(object["width"])) 
     70    except (KeyError, TypeError, ValueError):  
     71        width = 25 
     72 
     73    try:  
     74        height = units.toLength(eval(object["height"])) 
     75    except (KeyError, TypeError, ValueError):  
     76        height = 25 
     77 
     78    try:  
     79        rotation = eval(object["rotation"]) 
     80    except KeyError: 
     81        rotation = 0 
     82 
     83    if object["type"] == "rect": 
     84        d = shapes.Drawing(width, height) 
     85        d.rotate(rotation) 
     86 
     87        props = {} 
     88        ## props available in reportlab that we use: 
     89        ##   x,y,width,height 
     90        ##   fillColor: None for transparent, or (r,g,b) 
     91        ##   strokeColor: None for transparent, or (r,g,b) 
     92        ##   strokeDashArray: None 
     93        ##   strokeWidth: 0.25 
     94 
     95        ## props available that we don't currently use: 
     96        ##   rx, ry 
     97        ##   strokeMiterLimit: 0 
     98        ##   strokeLineJoin: 0 
     99        ##   strokeLineCap: 0 
     100        ## 
     101 
     102        try: 
     103            props["strokeWidth"] = units.toLength(eval(object["strokeWidth"])) 
     104        except KeyError:  
     105            props["strokeWidth"] = 1 
     106 
     107        try: 
     108            props["fillColor"] = eval(object["fillColor"]) 
     109        except KeyError: 
     110            props["fillColor"] = None 
     111 
     112        try: 
     113            props["strokeColor"] = eval(object["strokeColor"]) 
     114        except KeyError: 
     115            props["strokeColor"] = (0, 0, 0) 
     116 
     117        try: 
     118            props["strokeDashArray"] = eval(object["strokeDashArray"]) 
     119        except KeyError: 
     120            props["strokeDashArray"] = None 
     121 
     122        r = shapes.Rect(0, 0, width, height) 
     123        r.setProperties(props) 
     124        d.add(r) 
     125        d.drawOn(c, x, y) 
    89126 
    90127    elif object["type"] == "string": 
    91         try: borderWidth = object["borderWidth"] 
    92         except KeyError: borderWidth=0 
    93  
    94         if borderWidth <= 0: 
     128        c.translate(x, y) 
     129        c.rotate(rotation) 
     130        try:  
     131            borderWidth = units.toLength(eval(object["borderWidth"])) 
     132        except KeyError:  
     133            borderWidth = 0 
     134 
     135        try:  
     136            borderColor = eval(object["borderColor"]) 
     137        except KeyError:  
     138            borderColor = (0, 0, 0) 
     139 
     140        c.setLineWidth(borderWidth) 
     141        c.setStrokeColor(borderColor) 
     142 
     143        if borderWidth > 0: 
     144            stroke = 1 
     145        else: 
    95146            stroke = 0 
    96         else: 
    97             stroke = 1 
    98  
    99         c.setLineWidth(borderWidth) 
    100147 
    101148        if width is not None and height is not None: 
    102149            # clip the text to the specified width and height 
    103150            p = c.beginPath() 
    104             if object["alignment"] == "center": 
    105                 posx = x - (width/2) 
    106             elif object["alignment"] == "right": 
    107                 posx = x + width 
     151            if eval(object["align"]) == "center": 
     152                posx = (width / 2) 
     153            elif eval(object["align"]) == "right": 
     154                posx = width 
    108155            else: 
    109                 posx = x 
    110  
    111             p.rect(posx,y,width,height) 
     156                posx = 0 
     157 
     158            p.rect(posx, 0, width, height) 
    112159            c.clipPath(p, stroke=stroke) 
    113160 
     
    115162                 "right": c.drawRightString, 
    116163                 "left": c.drawString} 
    117         func = funcs[object["alignment"]] 
    118         fontFace = object["fontFace"] 
    119         fontSize = object["fontSize"] 
    120         c.setFont(fontFace, fontSize) 
    121         func(x,y,eval(object["expression"])) 
     164        func = funcs[eval(object["align"])] 
     165 
     166        try: 
     167            fontName = eval(object["fontName"]) 
     168        except KeyError: 
     169            fontName = "Helvetica" 
     170 
     171        try: 
     172            fontSize = eval(object["fontSize"]) 
     173        except KeyError: 
     174            fontSize = 10 
     175 
     176        try: 
     177            fillColor = eval(object["fillColor"]) 
     178        except KeyError: 
     179            fillColor = (0, 0, 0) 
     180 
     181        c.setFillColor(fillColor) 
     182        c.setFont(fontName, fontSize) 
     183 
     184        func(0,0,eval(object["expr"])) 
    122185 
    123186    elif object["type"] == "image": 
    124         try: mask = object["mask"] 
     187        try: mask = eval(object["mask"]) 
    125188        except: mask = None 
    126         c.drawImage(eval(object["expression"]), x, y, width, height, mask) 
     189        c.drawImage(eval(object["expr"]), x, y, width, height, mask) 
    127190    c.restoreState() 
    128191 
     
    131194for band in ("PageBackground", "PageHeader", "PageFooter"): 
    132195    bandDict = eval("form.%s" % band) 
    133     x = ml 
    134     if band == "PageHeader": 
    135         y = pageHeaderOrigin[1] 
    136     elif band == "PageFooter": 
    137         y = pageFooterOrigin[1] 
    138     elif band == "PageBackground": 
    139         x,y = 0,1 
     196 
     197    if showBands: 
     198        x = ml 
     199        if band == "PageHeader": 
     200            y = pageHeaderOrigin[1] 
     201        elif band == "PageFooter": 
     202            y = pageFooterOrigin[1] 
     203        elif band == "PageBackground": 
     204            x,y = 0,1 
    140205     
    141     if band == "PageBackground": 
    142         width, height = pageWidth-1, pageHeight-1 
    143     else: 
    144         width = pageWidth - ml - mr 
    145         height = bandDict["height"] * u 
    146  
    147     if showBands: 
     206        if band == "PageBackground": 
     207            width, height = pageWidth-1, pageHeight-1 
     208        else: 
     209            width = pageWidth - ml - mr 
     210            height = units.toLength(eval(bandDict["height"])) 
     211 
    148212        printBandOutline(band, x, y, width, height) 
    149213 
    150214    for object in bandDict["objects"]: 
    151         if bandDict == form.PageFooter: 
     215 
     216        if bandDict == form.PageHeader: 
     217            origin = pageHeaderOrigin 
     218        elif bandDict == form.PageFooter: 
    152219            origin = pageFooterOrigin 
    153         elif bandDict == form.PageHeader: 
    154             origin = pageHeaderOrigin 
    155220        elif bandDict == form.PageBackground: 
    156221            origin = (0,1) 
    157222 
    158         x = u*object["x"] + origin[0] 
    159         y = origin[1] + (u*object["y"]
     223        x = units.toLength(eval(object["x"])) + origin[0] 
     224        y = origin[1] + units.toLength(eval(object["y"])
    160225 
    161226        draw(object, x, y) 
     
    170235        bandDict = eval("form.%s" % band) 
    171236        x = ml 
    172         y = y - (u*bandDict["height"]
     237        y = y - units.toLength(eval(bandDict["height"])
    173238        width = pageWidth - ml - mr 
    174         height = bandDict["height"] * u 
     239        height = units.toLength(eval(bandDict["height"])) 
    175240 
    176241        if showBands: 
    177242            printBandOutline("%s (record %s)" % (band, recno), x, y, width, height) 
    178  
    179243        for object in bandDict["objects"]: 
    180             x = ml + (u*object["x"]
    181             y1 = y + (u*object["y"]
     244            x = ml + units.toLength(eval(object["x"])
     245            y1 = y + units.toLength(eval(object["y"])
    182246            draw(object, x, y1) 
    183247                 
  • trunk/reporting/samplespec.py

    r799 r804  
    55PageHeader, PageFooter, GroupHeader, GroupFooter, and Detail, and objects such 
    66as text boxes, rectangles, and lines. 
     7 
     8Most values are expressions to be evaluated at runtime (ie they are dynamic). 
    79""" 
    810 
    9 Page = {"unit": "inch", 
    10         "size": "letter", 
    11         "orientation": "portrait", 
    12         "margin": {"left": .5, 
    13                    "right": .5, 
    14                    "top": .5, 
    15                    "bottom": .5}, 
     11Page = {"size": ''' "letter" ''', 
     12        "orientation": ''' "portrait" ''', 
     13        "margin": {"left": ''' ".5 in" ''', 
     14                   "right": ''' ".5 in" ''', 
     15                   "top": ''' ".5 in" ''', 
     16                   "bottom": ''' ".5 in" '''}, 
    1617} 
    1718 
    1819 
    1920PageBackground = {"objects": [{"type": "string", 
    20                            "expression": '''"Test"''', 
    21                            "alignment": "center", 
    22                            "rotation": 30, 
    23                            "x": 4.25, 
    24                            "y": 5.5, 
    25                            "fontFace": "Helvetica", 
    26                            "fontSize": 12, 
    27                           }]} 
     21                           "expr": ''' "Test" ''', 
     22                           "align": ''' "left" ''', 
     23                           "rotation": ''' 55 ''', 
     24                           "x": ''' "4.25 in" ''', 
     25                           "y": ''' "5.5 in" ''', 
     26                           "width": ''' "1 in" ''', 
     27                           "fontName": ''' "Helvetica" ''', 
     28                           "fontSize": ''' 20 ''', 
     29                           "fillColor": ''' (.4, .1, .3) ''', 
     30                           "borderWidth": ''' ".5 pt" ''', 
     31                           "borderColor": ''' (.1,.8,.4) ''', 
     32                          }, 
     33                          {"type": "rect", 
     34                           "x": ''' "4.25 in" ''', 
     35                           "y": ''' "5 in" ''', 
     36                           "width": ''' "1 in" ''', 
     37                           "height": ''' ".25 in" ''', 
     38                           "rotation": ''' 45 ''', 
     39                           "strokeWidth": ''' ".25 pt" ''', 
     40                           "fillColor": ''' (.5,1,.5) ''', 
     41                           "strokeColor": ''' (.7,.2,.5) ''', 
     42                           "strokeDashArray": ''' (2,5,1,5) '''} 
     43]} 
    2844 
    2945 
    30 PageHeader = {"height": 0.5
     46PageHeader = {"height": ''' "0.5 in" '''
    3147              "objects": [{"type": "string", 
    32                            "expression": '''"Dabo's Favorite Artists"''', 
    33                            "alignment": "center"
    34                            "x": 3.75
    35                            "y": 0.3
    36                            "width": 6
    37                            "height": .25
    38                            "borderWidth": 0
    39                            "fontFace": "Helvetica"
    40                            "fontSize": 14
     48                           "expr": ''' "Dabo's Favorite Artists" ''', 
     49                           "align": ''' "center" '''
     50                           "x": ''' "3.75 in" '''
     51                           "y": ''' "0.3 in" '''
     52                           "width": ''' "6 in" '''
     53                           "height": ''' ".25 in" '''
     54                           "borderWidth": ''' "0 pt" '''
     55                           "fontFace": ''' "Helvetica" '''
     56                           "fontSize": ''' 14 '''
    4157                          }] 
    4258} 
    4359 
    44 PageFooter = {"height": 1.25
     60PageFooter = {"height": ''' "1.25 in" '''
    4561              "objects": [{"type": "image", 
    46                            "expression": '''"../icons/dabo_lettering_100x40.png"''', 
    47                            "x": 6.1
    48                            "y": .01
    49                            "width": None
    50                            "height": None
    51                            "mask": None
     62                           "expr": ''' "../icons/dabo_lettering_100x40.png" ''', 
     63                           "x": ''' "6.75 in" '''
     64                           "y": ''' "1 pt" '''
     65                           "width": ''' "50 pt" '''
     66                           "height": ''' "20 pt" '''
     67                           "mask": ''' None '''
    5268                          }] 
    5369} 
    5470 
    5571 
    56 Detail = {"height": .25
     72Detail = {"height": ''' ".25 in" '''
    5773          "objects": [{"type": "string", 
    58                        "expression": "record['cArtist']"
    59                        "alignment": "left"
    60                        "fontFace": "Helvetica"
    61                        "fontSize": 12
    62                        "borderWidth": .25
    63                        "x": 1
    64                        "y": .01
    65                        "width": 1.4
    66                        "height": 0.25 
     74                       "expr": ''' record['cArtist'] '''
     75                       "align": ''' "left" '''
     76                       "fontFace": ''' "Helvetica" '''
     77                       "fontSize": ''' 12 '''
     78                       "borderWidth": ''' ".25 pt" '''
     79                       "x": ''' "1 in" '''
     80                       "y": ''' "0 pt" '''
     81                       "width": ''' "1.4 in" '''
     82                       "height": ''' "0.25 in" ''' 
    6783                       }] 
    6884} 
    6985 
    70 Group1Header = {"height": .5
     86Group1Header = {"height": ''' ".5 in" '''
    7187                "objects": []} 
    7288 
    73 Group1Footer = {"height": 0
     89Group1Footer = {"height": ''' "0 in" '''
    7490                "objects": []} 
    7591 
    7692Groups = [{"name": "Group1", 
    77            "expression": "record['cartist']",} 
     93           "expr": ''' "record['cartist']" ''',} 
    7894         ]