def _image(self, node): import urllib from reportlab.lib.utils import ImageReader u = urllib.urlopen(str(node.getAttribute("file"))) s = StringIO.StringIO() s.write(u.read()) s.seek(0) img = ImageReader(s) (sx, sy) = img.getSize() args = {} for tag in ("width", "height", "x", "y"): if node.hasAttribute(tag): args[tag] = utils.unit_get(node.getAttribute(tag)) if ("width" in args) and (not "height" in args): args["height"] = sy * args["width"] / sx elif ("height" in args) and (not "width" in args): args["width"] = sx * args["height"] / sy elif ("width" in args) and ("height" in args): if (float(args["width"]) / args["height"]) > (float(sx) > sy): args["width"] = sx * args["height"] / sy else: args["height"] = sy * args["width"] / sx self.canvas.drawImage(img, **args)
def _ellipse(self, node): x1 = utils.unit_get(node.get("x")) x2 = utils.unit_get(node.get("width")) y1 = utils.unit_get(node.get("y")) y2 = utils.unit_get(node.get("height")) self.canvas.ellipse(x1, y1, x2, y2, **utils.attr_get(node, [], {"fill": "bool", "stroke": "bool"}))
def _image(self, node): import urllib from reportlab.lib.utils import ImageReader u = urllib.urlopen(str(node.getAttribute('file'))) s = StringIO.StringIO() s.write(u.read()) s.seek(0) img = ImageReader(s) (sx,sy) = img.getSize() args = {} for tag in ('width','height','x','y'): if node.hasAttribute(tag): if not utils.unit_get(node.getAttribute(tag)): continue args[tag] = utils.unit_get(node.getAttribute(tag)) if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args): if (float(args['width'])/args['height'])>(float(sx)>sy): args['width'] = sx * args['height'] / sy else: args['height'] = sy * args['width'] / sx self.canvas.drawImage(img, **args)
def __init__(self, out, node, doc): if not node.hasAttribute('pageSize'): pageSize = (utils.unit_get('21cm'), utils.unit_get('29.7cm')) else: ps = map(lambda x:x.strip(), node.getAttribute('pageSize').replace(')', '').replace('(', '').split(',')) pageSize = ( utils.unit_get(ps[0]),utils.unit_get(ps[1]) ) cm = reportlab.lib.units.cm self.doc_tmpl = platypus.BaseDocTemplate(out, pagesize=pageSize, **utils.attr_get(node, ['leftMargin','rightMargin','topMargin','bottomMargin'], {'allowSplitting':'int','showBoundary':'bool','title':'str','author':'str'})) self.page_templates = [] self.styles = doc.styles self.doc_tmpl.styles = doc.styles # hack self.doc = doc pts = node.getElementsByTagName('pageTemplate') for pt in pts: frames = [] for frame_el in pt.getElementsByTagName('frame'): frame = platypus.Frame( **(utils.attr_get(frame_el, ['x1','y1', 'width','height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding'], {'id':'text', 'showBoundary':'bool'})) ) frames.append( frame ) gr = pt.getElementsByTagName('pageGraphics') if len(gr): drw = _rml_draw(gr[0]) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) else: self.page_templates.append( platypus.PageTemplate(frames=frames, **utils.attr_get(pt, [], {'id':'str'}) )) self.doc_tmpl.addPageTemplates(self.page_templates)
def _table(self, node): length = 0 colwidths = None rowheights = None data = [] for tr in _child_get(node,'tr'): data2 = [] for td in _child_get(tr, 'td'): flow = [] for n in td.childNodes: if n.nodeType==node.ELEMENT_NODE: flow.append( self._flowable(n) ) if not len(flow): flow = self._textual(td) data2.append( flow ) if len(data2)>length: length=len(data2) for ab in data: while len(ab)<length: ab.append('') while len(data2)<length: data2.append('') data.append( data2 ) if node.hasAttribute('colWidths'): assert length == len(node.getAttribute('colWidths').split(',')) colwidths = [utils.unit_get(f.strip()) for f in node.getAttribute('colWidths').split(',')] if node.hasAttribute('rowHeights'): rowheights = [utils.unit_get(f.strip()) for f in node.getAttribute('rowHeights').split(',')] table = platypus.Table(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'}))) if node.hasAttribute('style'): table.setStyle(self.styles.table_styles[node.getAttribute('style')]) return table
def _ellipse(self, node): x1 = utils.unit_get(node.get('x')) x2 = utils.unit_get(node.get('width')) y1 = utils.unit_get(node.get('y')) y2 = utils.unit_get(node.get('height')) self.canvas.ellipse(x1,y1,x2,y2, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
def __init__(self, node, localcontext, styles, self2): self.localcontext = (localcontext or {}).copy() self.node = node self.styles = styles self.width = utils.unit_get(node.get('width')) self.height = utils.unit_get(node.get('height')) self.self2 = self2
def _circle(self, node): self.canvas.circle( x_cen=utils.unit_get(node.getAttribute("x")), y_cen=utils.unit_get(node.getAttribute("y")), r=utils.unit_get(node.getAttribute("radius")), **utils.attr_get(node, [], {"fill": "bool", "stroke": "bool"}) )
def __init__(self, localcontext, out, node, doc, images={}, path='.', title=None): self.localcontext = localcontext self.images= images self.path = path self.title = title if not node.get('pageSize'): pageSize = (utils.unit_get('21cm'), utils.unit_get('29.7cm')) else: ps = map(lambda x:x.strip(), node.get('pageSize').replace(')', '').replace('(', '').split(',')) pageSize = ( utils.unit_get(ps[0]),utils.unit_get(ps[1]) ) self.doc_tmpl = TinyDocTemplate(out, pagesize=pageSize, **utils.attr_get(node, ['leftMargin','rightMargin','topMargin','bottomMargin'], {'allowSplitting':'int','showBoundary':'bool','title':'str','author':'str'})) self.page_templates = [] self.styles = doc.styles self.doc = doc pts = node.findall('pageTemplate') for pt in pts: frames = [] for frame_el in pt.findall('frame'): frame = platypus.Frame( **(utils.attr_get(frame_el, ['x1','y1', 'width','height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding'], {'id':'str', 'showBoundary':'bool'})) ) if utils.attr_get(frame_el, ['last']): frame.lastFrame = True frames.append( frame ) try : gr = pt.findall('pageGraphics')\ or pt[1].findall('pageGraphics') except Exception: # FIXME: be even more specific, perhaps? gr='' if len(gr): drw = _rml_draw(self.localcontext,gr[0], self.doc, images=images, path=self.path, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) else: drw = _rml_draw(self.localcontext,node,self.doc,title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames,onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) self.doc_tmpl.addPageTemplates(self.page_templates)
def _textual(self, node): rc = '' for n in node.childNodes: if n.nodeType == n.ELEMENT_NODE: if n.localName.startswith('seq'): rc += str(_rml_sequence(n)) elif n.localName == 'name': x, y = n.getAttribute('x'), n.getAttribute('y') fontName, fontSize, fontColor = n.getAttribute('fontName'), n.getAttribute('fontSize'), n.getAttribute('fontColor') if not fontName: fontName = self.canvas._fontname if not fontSize: fontSize = self.canvas._fontsize global named_string_styles named_string_styles[n.getAttribute('id')] = ( fontName, fontSize, fontColor ) if x and y: x, y = utils.unit_get(x), utils.unit_get(y) self.canvas.translate(x, y) self.canvas.doForm(n.getAttribute('id')) if x and y: self.canvas.translate(-x, -y) elif n.localName=='pageNumber': rc += str(self.canvas.getPageNumber()) elif n.localName == 'evalString': rc += _eval_string(n, textual=self) elif (n.nodeType == node.CDATA_SECTION_NODE): rc += n.data elif (n.nodeType == node.TEXT_NODE): rc += n.data return rc.encode(self.encoding)
def _flowable(self, node): # FIXME: speedup if node.localName=='para': style = self.styles.para_style_get(node) # ERROR return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'}))) elif node.localName=='name': self.styles.names[ node.getAttribute('id')] = node.getAttribute('value') return None elif node.localName=='xpre': style = self.styles.para_style_get(node) return platypus.XPreformatted(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str','dedent':'int','frags':'int'}))) elif node.localName=='pre': style = self.styles.para_style_get(node) return platypus.Preformatted(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str','dedent':'int'}))) elif node.localName=='illustration': return self._illustration(node) elif node.localName=='blockTable': return self._table(node) elif node.localName=='title': styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Title'] return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'}))) elif node.localName=='h1': styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Heading1'] return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'}))) elif node.localName=='h2': styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Heading2'] return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'}))) elif node.localName=='h3': styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Heading3'] return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'}))) elif node.localName=='image': return platypus.Image(node.getAttribute('file'), mask=(250,255,250,255,250,255), **(utils.attr_get(node, ['width','height']))) elif node.localName=='spacer': if node.hasAttribute('width'): width = utils.unit_get(node.getAttribute('width')) else: width = utils.unit_get('1cm') length = utils.unit_get(node.getAttribute('length')) return platypus.Spacer(width=width, height=length) elif node.localName=='pageBreak': return platypus.PageBreak() elif node.localName=='condPageBreak': return platypus.CondPageBreak(**(utils.attr_get(node, ['height']))) elif node.localName=='setNextTemplate': return platypus.NextPageTemplate(str(node.getAttribute('name'))) elif node.localName=='nextFrame': return platypus.CondPageBreak(1000) # TODO: change the 1000 ! elif barcode_codes and node.localName=='barCodeFlowable': code = barcode_codes.get(node.getAttribute('code'), Code128) return code( self._textual(node), **utils.attr_get(node, ['barWidth', 'barHeight'], {'fontName': 'str', 'humanReadable': 'bool'})) else: sys.stderr.write('Warning: flowable not yet implemented: %s !\n' % (node.localName,)) return None
def _translate(self, node): dx = 0 dy = 0 if node.hasAttribute("dx"): dx = utils.unit_get(node.getAttribute("dx")) if node.hasAttribute("dy"): dy = utils.unit_get(node.getAttribute("dy")) self.canvas.translate(dx, dy)
def __init__(self, node, style): self.posx = utils.unit_get(node.get('x')) self.posy = utils.unit_get(node.get('y')) aligns = { 'drawString': 'left', 'drawRightString': 'right', 'drawCentredString': 'center' } align = aligns[node.localName] self.pos = [(self.posx, self.posy, align, utils.text_get(node), style.get('td'), style.font_size_get('td'))]
def __init__(self, node, style,localcontext = {}): self.localcontext = localcontext self.posx = utils.unit_get(node.get('x')) self.posy = utils.unit_get(node.get('y')) aligns = { 'drawString': 'left', 'drawRightString': 'right', 'drawCentredString': 'center' } align = aligns[node.tag] self.pos = [(self.posx, self.posy, align, utils._process_text(self, node.text), style.get('td'), style.font_size_get('td'))]
def __init__(self, out, node, doc): if not node.hasAttribute("pageSize"): pageSize = (utils.unit_get("21cm"), utils.unit_get("29.7cm")) else: ps = map(lambda x: x.strip(), node.getAttribute("pageSize").replace(")", "").replace("(", "").split(",")) pageSize = (utils.unit_get(ps[0]), utils.unit_get(ps[1])) cm = reportlab.lib.units.cm self.doc_tmpl = platypus.BaseDocTemplate( out, pagesize=pageSize, **utils.attr_get( node, ["leftMargin", "rightMargin", "topMargin", "bottomMargin"], {"allowSplitting": "int", "showBoundary": "bool", "title": "str", "author": "str"}, ) ) self.page_templates = [] self.styles = doc.styles self.doc = doc pts = node.getElementsByTagName("pageTemplate") for pt in pts: frames = [] for frame_el in pt.getElementsByTagName("frame"): frame = platypus.Frame( **( utils.attr_get( frame_el, [ "x1", "y1", "width", "height", "leftPadding", "rightPadding", "bottomPadding", "topPadding", ], {"id": "text", "showBoundary": "bool"}, ) ) ) frames.append(frame) gr = pt.getElementsByTagName("pageGraphics") if len(gr): drw = _rml_draw(gr[0], self.doc) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {"id": "str"})) ) else: self.page_templates.append( platypus.PageTemplate(frames=frames, **utils.attr_get(pt, [], {"id": "str"})) ) self.doc_tmpl.addPageTemplates(self.page_templates)
def _image(self, node): #add attribute 'src' to tag 'image' by xiandong.xie s = StringIO.StringIO() if node.hasAttribute('src'): import base64 imgdata = base64.b64decode(node.getAttribute('src')) s.write(imgdata) else: import urllib u = urllib.urlopen(str(node.getAttribute('file'))) s.write(u.read()) from reportlab.lib.utils import ImageReader s.seek(0) img = ImageReader(s) (sx,sy) = img.getSize() args = {} for tag in ('width','height','x','y'): if node.hasAttribute(tag): args[tag] = utils.unit_get(node.getAttribute(tag)) if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args): if (float(args['width'])/args['height'])>(float(sx)>sy): args['width'] = sx * args['height'] / sy else: args['height'] = sy * args['width'] / sx self.canvas.drawImage(img, **args)
def _para_style_update(self, style, node): for attr in ["textColor", "backColor", "bulletColor"]: if node.hasAttribute(attr): style.__dict__[attr] = color.get(node.getAttribute(attr)) for attr in ["fontName", "bulletFontName", "bulletText"]: if node.hasAttribute(attr): style.__dict__[attr] = node.getAttribute(attr) for attr in [ "fontSize", "leftIndent", "rightIndent", "spaceBefore", "spaceAfter", "firstLineIndent", "bulletIndent", "bulletFontSize", "leading", ]: if node.hasAttribute(attr): style.__dict__[attr] = utils.unit_get(node.getAttribute(attr)) if node.hasAttribute("alignment"): align = { "right": reportlab.lib.enums.TA_RIGHT, "center": reportlab.lib.enums.TA_CENTER, "justify": reportlab.lib.enums.TA_JUSTIFY, } style.alignment = align.get(node.getAttribute("alignment").lower(), reportlab.lib.enums.TA_LEFT) return style
def setFont(self, node): from reportlab.pdfbase import pdfmetrics fname = node.get('name') #TODO : other fonts should be supported if fname not in pdfmetrics.standardFonts: fname = self.canvas._fontname return self.canvas.setFont(fname, utils.unit_get(node.get('size')))
def _line_mode(self, node): ljoin = {'round':1, 'mitered':0, 'bevelled':2} lcap = {'default':0, 'round':1, 'square':2} if node.hasAttribute('width'): self.canvas.setLineWidth(utils.unit_get(node.getAttribute('width'))) if node.hasAttribute('join'): self.canvas.setLineJoin(ljoin[node.getAttribute('join')]) if node.hasAttribute('cap'): self.canvas.setLineCap(lcap[node.getAttribute('cap')]) if node.hasAttribute('miterLimit'): self.canvas.setDash(utils.unit_get(node.getAttribute('miterLimit'))) if node.hasAttribute('dash'): dashes = node.getAttribute('dash').split(',') for x in range(len(dashes)): dashes[x]=utils.unit_get(dashes[x]) self.canvas.setDash(node.getAttribute('dash').split(','))
def render(self, node): tags = { "drawCentredString": self._drawCenteredString, "drawRightString": self._drawRightString, "drawString": self._drawString, "rect": self._rect, "ellipse": self._ellipse, "lines": self._lines, "grid": self._grid, "curves": self._curves, "fill": lambda node: self.canvas.setFillColor(color.get(node.getAttribute("color"))), "stroke": lambda node: self.canvas.setStrokeColor(color.get(node.getAttribute("color"))), "setFont": lambda node: self.canvas.setFont( node.getAttribute("name"), utils.unit_get(node.getAttribute("size")) ), "place": self._place, "circle": self._circle, "lineMode": self._line_mode, "path": self._path, "rotate": lambda node: self.canvas.rotate(float(node.getAttribute("degrees"))), "translate": self._translate, "image": self._image, } for nd in node.childNodes: if nd.nodeType == nd.ELEMENT_NODE: for tag in tags: if nd.localName == tag: tags[tag](nd) break
def _line_mode(self, node): ljoin = {"round": 1, "mitered": 0, "bevelled": 2} lcap = {"default": 0, "round": 1, "square": 2} if node.hasAttribute("width"): self.canvas.setLineWidth(utils.unit_get(node.getAttribute("width"))) if node.hasAttribute("join"): self.canvas.setLineJoin(ljoin[node.getAttribute("join")]) if node.hasAttribute("cap"): self.canvas.setLineCap(lcap[node.getAttribute("cap")]) if node.hasAttribute("miterLimit"): self.canvas.setDash(utils.unit_get(node.getAttribute("miterLimit"))) if node.hasAttribute("dash"): dashes = node.getAttribute("dash").split(",") for x in range(len(dashes)): dashes[x] = utils.unit_get(dashes[x]) self.canvas.setDash(node.getAttribute("dash").split(","))
def render(self, node): tags = { 'drawCentredString': self._drawCenteredString, 'drawRightString': self._drawRightString, 'drawString': self._drawString, 'rect': self._rect, 'ellipse': self._ellipse, 'lines': self._lines, 'grid': self._grid, 'curves': self._curves, 'fill': lambda node: self.canvas.setFillColor(color.get(node.getAttribute('color'))), 'stroke': lambda node: self.canvas.setStrokeColor(color.get(node.getAttribute('color'))), 'setFont': lambda node: self.canvas.setFont(node.getAttribute('name'), utils.unit_get(node.getAttribute('size'))), 'place': self._place, 'circle': self._circle, 'lineMode': self._line_mode, 'path': self._path, 'rotate': lambda node: self.canvas.rotate(float(node.getAttribute('degrees'))), 'translate': self._translate, 'image': self._image } for nd in node.childNodes: if nd.nodeType==nd.ELEMENT_NODE: for tag in tags: if nd.localName==tag: tags[tag](nd) break
def _para_style_update(self, node): data = {} for attr in ['textColor', 'backColor', 'bulletColor', 'borderColor']: if node.get(attr): data[attr] = color.get(node.get(attr)) for attr in ['bulletFontName', 'fontName']: if node.get(attr): fontname= select_fontname(node.get(attr), None) if fontname is not None: data['fontName'] = fontname for attr in ['bulletText']: if node.get(attr): data[attr] = node.get(attr) for attr in ['fontSize', 'leftIndent', 'rightIndent', 'spaceBefore', 'spaceAfter', 'firstLineIndent', 'bulletIndent', 'bulletFontSize', 'leading', 'borderWidth','borderPadding','borderRadius']: if node.get(attr): data[attr] = utils.unit_get(node.get(attr)) if node.get('alignment'): align = { 'right':reportlab.lib.enums.TA_RIGHT, 'center':reportlab.lib.enums.TA_CENTER, 'justify':reportlab.lib.enums.TA_JUSTIFY } data['alignment'] = align.get(node.get('alignment').lower(), reportlab.lib.enums.TA_LEFT) return data
def _tag_table(self, node): new_node = copy.deepcopy(node) for child in new_node: new_node.remove(child) new_node.tag = 'table' def process(node,new_node): for child in utils._child_get(node,self): new_child = copy.deepcopy(child) new_node.append(new_child) if len(child): for n in new_child: new_child.remove(n) process(child, new_child) else: new_child.text = utils._process_text(self, child.text) new_child.tag = 'p' try: if new_child.get('style').find('terp_tblheader')!= -1: new_node.tag = 'th' except: pass process(node,new_node) if new_node.get('colWidths',False): sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(',')) tr = etree.SubElement(new_node, 'tr') for s in sizes: etree.SubElement(tr, 'td', width=str(s)) return etree.tostring(new_node)
def _image(self, node): import urllib from reportlab.lib.utils import ImageReader u = urllib.urlopen(str(node.getAttribute('file'))) s = StringIO.StringIO() s.write(u.read()) s.seek(0) img = ImageReader(s) (sx,sy) = img.getSize() args = {} for tag in ('width','height','x','y'): if node.hasAttribute(tag): args[tag] = utils.unit_get(node.getAttribute(tag)) if node.hasAttribute("preserveAspectRatio"): args["preserveAspectRatio"] = True if node.hasAttribute("mask"): args["mask"] = node.getAttribute("mask") if node.hasAttribute("anchor"): args["anchor"] = node.getAttribute("anchor") if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args) and (not args.get("preserveAspectRatio", False)): #if (float(args['width'])/args['height'])>(float(sx)>sy): # args['width'] = sx * args['height'] / sy #else: # args['height'] = sy * args['width'] / sx pass self.canvas.drawImage(img, **args)
def _tag_table(self, node): self.tb.fline() saved_tb = self.tb self.tb = None sizes = None if node.get('colWidths'): sizes = map(lambda x: utils.unit_get(x), node.get('colWidths').split(',')) trs = [] for n in utils._child_get(node,self): if n.tag == 'tr': tds = [] for m in utils._child_get(n,self): if m.tag == 'td': self.tb = textbox() self.rec_render_cnodes(m) tds.append(self.tb) self.tb = None if len(tds): trs.append(tds) if not sizes: verbose("computing table sizes..") for tds in trs: trt = textbox() off=0 for i in range(len(tds)): p = int(sizes[i]/Font_size) trl = tds[i].renderlines(pad=p) trt.haplines(trl,off) off += sizes[i]/Font_size saved_tb.curline = trt saved_tb.fline() self.tb = saved_tb return
def _lines(self, node): line_str = utils.text_get(node).split() lines = [] while len(line_str) > 3: lines.append([utils.unit_get(l) for l in line_str[0:4]]) line_str = line_str[4:] self.canvas.lines(lines)
def _rect(self, node): if node.hasAttribute("round"): self.canvas.roundRect( radius=utils.unit_get(node.getAttribute("round")), **utils.attr_get(node, ["x", "y", "width", "height"], {"fill": "bool", "stroke": "bool"}) ) else: self.canvas.rect(**utils.attr_get(node, ["x", "y", "width", "height"], {"fill": "bool", "stroke": "bool"}))
def __init__(self, localcontext, out, node, doc, images=None, path='.', title=None): if images is None: images = {} if not localcontext: localcontext={'internal_header':True} self.localcontext = localcontext self.images= images self.path = path self.title = title pagesize_map = {'a4': A4, 'us_letter': letter } pageSize = A4 if self.localcontext.get('company'): pageSize = pagesize_map.get(self.localcontext.get('company').paper_format, A4) if node.get('pageSize'): ps = map(lambda x:x.strip(), node.get('pageSize').replace(')', '').replace('(', '').split(',')) pageSize = ( utils.unit_get(ps[0]),utils.unit_get(ps[1]) ) self.doc_tmpl = TinyDocTemplate(out, pagesize=pageSize, **utils.attr_get(node, ['leftMargin','rightMargin','topMargin','bottomMargin'], {'allowSplitting':'int','showBoundary':'bool','rotation':'int','title':'str','author':'str'})) self.page_templates = [] self.styles = doc.styles self.doc = doc self.image=[] pts = node.findall('pageTemplate') for pt in pts: frames = [] for frame_el in pt.findall('frame'): frame = platypus.Frame( **(utils.attr_get(frame_el, ['x1','y1', 'width','height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding'], {'id':'str', 'showBoundary':'bool'})) ) if utils.attr_get(frame_el, ['last']): frame.lastFrame = True frames.append( frame ) try : gr = pt.findall('pageGraphics')\ or pt[1].findall('pageGraphics') except Exception: # FIXME: be even more specific, perhaps? gr='' if len(gr): # self.image=[ n for n in utils._child_get(gr[0], self) if n.tag=='image' or not self.localcontext] drw = _rml_draw(self.localcontext,gr[0], self.doc, images=images, path=self.path, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) else: drw = _rml_draw(self.localcontext,node,self.doc,title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames,onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) self.doc_tmpl.addPageTemplates(self.page_templates)
def _barcode(self, node): from reportlab.graphics.barcode import code128 createargs = {} drawargs = {} for tag in ('x', 'y'): if node.hasAttribute(tag): drawargs[tag] = utils.unit_get(node.getAttribute(tag)) for tag in ('barWidth', 'barHeight'): if node.hasAttribute(tag): createargs[tag] = utils.unit_get(node.getAttribute(tag)) barcode = code128.Code128(self._textual(node), **createargs) barcode.drawOn(self.canvas, **drawargs)
def setFont(self, node): fontname = select_fontname(node.get('name'), self.canvas._fontname) return self.canvas.setFont(fontname, utils.unit_get(node.get('size')))
def _tag_spacer(self, node): length = 1+int(utils.unit_get(node.get('length')))/35 return "\n"*length
def __init__(self, localcontext, out, node, doc, images={}, path='.', title=None): self.localcontext = localcontext self.images = images self.path = path self.title = title if not node.get('pageSize'): pageSize = (utils.unit_get('21cm'), utils.unit_get('29.7cm')) else: ps = map( lambda x: x.strip(), node.get('pageSize').replace(')', '').replace('(', '').split(',')) pageSize = (utils.unit_get(ps[0]), utils.unit_get(ps[1])) self.doc_tmpl = TinyDocTemplate( out, pagesize=pageSize, **utils.attr_get( node, ['leftMargin', 'rightMargin', 'topMargin', 'bottomMargin'], { 'allowSplitting': 'int', 'showBoundary': 'bool', 'title': 'str', 'author': 'str' })) self.page_templates = [] self.styles = doc.styles self.doc = doc pts = node.findall('pageTemplate') for pt in pts: frames = [] for frame_el in pt.findall('frame'): frame = platypus.Frame( **(utils.attr_get(frame_el, [ 'x1', 'y1', 'width', 'height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding' ], { 'id': 'str', 'showBoundary': 'bool' }))) if utils.attr_get(frame_el, ['last']): frame.lastFrame = True frames.append(frame) try: gr = pt.findall('pageGraphics')\ or pt[1].findall('pageGraphics') except Exception: # FIXME: be even more specific, perhaps? gr = '' if len(gr): drw = _rml_draw(self.localcontext, gr[0], self.doc, images=images, path=self.path, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get( pt, [], {'id': 'str'}))) else: drw = _rml_draw(self.localcontext, node, self.doc, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get( pt, [], {'id': 'str'}))) self.doc_tmpl.addPageTemplates(self.page_templates)
def __init__(self, localcontext, out, node, doc, images=None, path='.', title=None): if images is None: images = {} if not localcontext: localcontext = {'internal_header': True} self.localcontext = localcontext self.images = images self.path = path self.title = title pagesize_map = {'a4': A4, 'us_letter': letter} pageSize = A4 if self.localcontext.get('company'): pageSize = pagesize_map.get( self.localcontext.get('company').paper_format, A4) if node.get('pageSize'): ps = map( lambda x: x.strip(), node.get('pageSize').replace(')', '').replace('(', '').split(',')) pageSize = (utils.unit_get(ps[0]), utils.unit_get(ps[1])) self.doc_tmpl = TinyDocTemplate( out, pagesize=pageSize, **utils.attr_get( node, ['leftMargin', 'rightMargin', 'topMargin', 'bottomMargin'], { 'allowSplitting': 'int', 'showBoundary': 'bool', 'rotation': 'int', 'title': 'str', 'author': 'str' })) self.page_templates = [] self.styles = doc.styles self.doc = doc self.image = [] pts = node.findall('pageTemplate') for pt in pts: frames = [] for frame_el in pt.findall('frame'): frame = platypus.Frame( **(utils.attr_get(frame_el, [ 'x1', 'y1', 'width', 'height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding' ], { 'id': 'str', 'showBoundary': 'bool' }))) if utils.attr_get(frame_el, ['last']): frame.lastFrame = True frames.append(frame) try: gr = pt.findall('pageGraphics')\ or pt[1].findall('pageGraphics') except Exception: # FIXME: be even more specific, perhaps? gr = '' if len(gr): # self.image=[ n for n in utils._child_get(gr[0], self) if n.tag=='image' or not self.localcontext] drw = _rml_draw(self.localcontext, gr[0], self.doc, images=images, path=self.path, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get( pt, [], {'id': 'str'}))) else: drw = _rml_draw(self.localcontext, node, self.doc, title=self.title) self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get( pt, [], {'id': 'str'}))) self.doc_tmpl.addPageTemplates(self.page_templates)
def _grid(self, node): xlist = [utils.unit_get(s) for s in node.get('xs').split(',')] ylist = [utils.unit_get(s) for s in node.get('ys').split(',')] self.canvas.grid(xlist, ylist)
def _translate(self, node): dx = utils.unit_get(node.get('dx')) or 0 dy = utils.unit_get(node.get('dy')) or 0 self.canvas.translate(dx, dy)
def _image(self, node): import urllib import urlparse from reportlab.lib.utils import ImageReader nfile = node.get('file') if not nfile: if node.get('name'): image_data = self.images[node.get('name')] _logger.debug("Image %s used", node.get('name')) s = StringIO(image_data) else: newtext = node.text if self.localcontext: res = utils._regex.findall(newtext) for key in res: newtext = eval(key, {}, self.localcontext) or '' image_data = None if newtext: image_data = base64.decodestring(newtext) if image_data: s = StringIO(image_data) else: _logger.debug("No image data!") return False else: if nfile in self.images: s = StringIO(self.images[nfile]) else: try: up = urlparse.urlparse(str(nfile)) except ValueError: up = False if up and up.scheme: # RFC: do we really want to open external URLs? # Are we safe from cross-site scripting or attacks? _logger.debug("Retrieve image from %s", nfile) u = urllib.urlopen(str(nfile)) s = StringIO(u.read()) else: _logger.debug("Open image file %s ", nfile) s = _open_image(nfile, path=self.path) try: img = ImageReader(s) (sx, sy) = img.getSize() _logger.debug("Image is %dx%d", sx, sy) args = {'x': 0.0, 'y': 0.0} for tag in ('width', 'height', 'x', 'y'): if node.get(tag): args[tag] = utils.unit_get(node.get(tag)) if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args): if (float(args['width']) / args['height']) > (float(sx) > sy): args['width'] = sx * args['height'] / sy else: args['height'] = sy * args['width'] / sx self.canvas.drawImage(img, **args) finally: s.close()
mask=(250, 255, 250, 255, 250, 255), **(utils.attr_get( node, ['width', 'height']))) else: return platypus.Image(node.get('file'), mask=(250, 255, 250, 255, 250, 255), **(utils.attr_get( node, ['width', 'height']))) from reportlab.lib.utils import ImageReader name = str(node.get('file')) img = ImageReader(name) (sx, sy) = img.getSize() args = {} for tag in ('width', 'height'): if node.get(tag): args[tag] = utils.unit_get(node.get(tag)) if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args): if (float(args['width']) / args['height']) > (float(sx) > sy): args['width'] = sx * args['height'] / sy else: args['height'] = sy * args['width'] / sx return platypus.Image(name, mask=(250, 255, 250, 255, 250, 255), **args) elif node.tag == 'spacer': if node.get('width'): width = utils.unit_get(node.get('width'))
def _circle(self, node): self.canvas.circle(x_cen=utils.unit_get(node.get('x')), y_cen=utils.unit_get(node.get('y')), r=utils.unit_get(node.get('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
def _flowable(self, node, extra_style=None): if node.tag == 'pto': return self._pto(node) if node.tag == 'para': style = self.styles.para_style_get(node) if extra_style: style.__dict__.update(extra_style) result = [] for i in self._textual(node).split('\n'): result.append( platypus.Paragraph( i, style, **(utils.attr_get(node, [], {'bulletText': 'str'})))) return result elif node.tag == 'barCode': try: from reportlab.graphics.barcode import code128 from reportlab.graphics.barcode import code39 from reportlab.graphics.barcode import code93 from reportlab.graphics.barcode import common from reportlab.graphics.barcode import fourstate from reportlab.graphics.barcode import usps from reportlab.graphics.barcode import createBarcodeDrawing except ImportError: _logger.warning("Cannot use barcode renderers:", exc_info=True) return None args = utils.attr_get( node, [], { 'ratio': 'float', 'xdim': 'unit', 'height': 'unit', 'checksum': 'int', 'quiet': 'int', 'width': 'unit', 'stop': 'bool', 'bearers': 'int', 'barWidth': 'float', 'barHeight': 'float' }) codes = { 'codabar': lambda x: common.Codabar(x, **args), 'code11': lambda x: common.Code11(x, **args), 'code128': lambda x: code128.Code128(str(x), **args), 'standard39': lambda x: code39.Standard39(str(x), **args), 'standard93': lambda x: code93.Standard93(str(x), **args), 'i2of5': lambda x: common.I2of5(x, **args), 'extended39': lambda x: code39.Extended39(str(x), **args), 'extended93': lambda x: code93.Extended93(str(x), **args), 'msi': lambda x: common.MSI(x, **args), 'fim': lambda x: usps.FIM(x, **args), 'postnet': lambda x: usps.POSTNET(x, **args), 'ean13': lambda x: createBarcodeDrawing('EAN13', value=str(x), **args), 'qrcode': lambda x: createBarcodeDrawing('QR', value=x, **args), } code = 'code128' if node.get('code'): code = node.get('code').lower() return codes[code](self._textual(node)) elif node.tag == 'name': self.styles.names[node.get('id')] = node.get('value') return None elif node.tag == 'xpre': style = self.styles.para_style_get(node) return platypus.XPreformatted( self._textual(node), style, **(utils.attr_get(node, [], { 'bulletText': 'str', 'dedent': 'int', 'frags': 'int' }))) elif node.tag == 'pre': style = self.styles.para_style_get(node) return platypus.Preformatted( self._textual(node), style, **(utils.attr_get(node, [], { 'bulletText': 'str', 'dedent': 'int' }))) elif node.tag == 'illustration': return self._illustration(node) elif node.tag == 'blockTable': return self._table(node) elif node.tag == 'title': styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Title'] return platypus.Paragraph( self._textual(node), style, **(utils.attr_get(node, [], {'bulletText': 'str'}))) elif re.match('^h([1-9]+[0-9]*)$', (node.tag or '')): styles = reportlab.lib.styles.getSampleStyleSheet() style = styles['Heading' + str(node.tag[1:])] return platypus.Paragraph( self._textual(node), style, **(utils.attr_get(node, [], {'bulletText': 'str'}))) elif node.tag == 'image': image_data = False if not node.get('file'): if node.get('name'): if node.get('name') in self.doc.images: _logger.debug("Image %s read ", node.get('name')) image_data = self.doc.images[node.get('name')].read() else: _logger.warning("Image %s not defined", node.get('name')) return False else: import base64 newtext = node.text if self.localcontext: newtext = utils._process_text(self, node.text or '') image_data = base64.decodestring(newtext) if not image_data: _logger.debug("No inline image data") return False image = StringIO(image_data) else: _logger.debug("Image get from file %s", node.get('file')) image = _open_image(node.get('file'), path=self.doc.path) return platypus.Image(image, mask=(250, 255, 250, 255, 250, 255), **(utils.attr_get(node, ['width', 'height']))) elif node.tag == 'spacer': if node.get('width'): width = utils.unit_get(node.get('width')) else: width = utils.unit_get('1cm') length = utils.unit_get(node.get('length')) return platypus.Spacer(width=width, height=length) elif node.tag == 'section': return self.render(node) elif node.tag == 'pageNumberReset': return PageReset() elif node.tag in ('pageBreak', 'nextPage'): return platypus.PageBreak() elif node.tag == 'condPageBreak': return platypus.CondPageBreak(**(utils.attr_get(node, ['height']))) elif node.tag == 'setNextTemplate': return platypus.NextPageTemplate(str(node.get('name'))) elif node.tag == 'nextFrame': return platypus.CondPageBreak(1000) # TODO: change the 1000 ! elif node.tag == 'setNextFrame': from reportlab.platypus.doctemplate import NextFrameFlowable return NextFrameFlowable(str(node.get('name'))) elif node.tag == 'currentFrame': from reportlab.platypus.doctemplate import CurrentFrameFlowable return CurrentFrameFlowable(str(node.get('name'))) elif node.tag == 'frameEnd': return EndFrameFlowable() elif node.tag == 'hr': width_hr = node.get('width') or '100%' color_hr = node.get('color') or 'black' thickness_hr = node.get('thickness') or 1 lineCap_hr = node.get('lineCap') or 'round' return platypus.flowables.HRFlowable(width=width_hr, color=color.get(color_hr), thickness=float(thickness_hr), lineCap=str(lineCap_hr)) else: sys.stderr.write('Warning: flowable not yet implemented: %s !\n' % (node.tag, )) return None
def _curves(self, node): line_str = node.text.split() lines = [] while len(line_str)>7: self.canvas.bezier(*[utils.unit_get(l) for l in line_str[0:8]]) line_str = line_str[8:]
def _table(self, node): children = utils._child_get(node, self, 'tr') if not children: return None length = 0 colwidths = None rowheights = None data = [] styles = [] posy = 0 for tr in children: paraStyle = None if tr.get('style'): st = copy.deepcopy(self.styles.table_styles[tr.get('style')]) for si in range(len(st._cmds)): s = list(st._cmds[si]) s[1] = (s[1][0], posy) s[2] = (s[2][0], posy) st._cmds[si] = tuple(s) styles.append(st) if tr.get('paraStyle'): paraStyle = self.styles.styles[tr.get('paraStyle')] data2 = [] posx = 0 for td in utils._child_get(tr, self, 'td'): if td.get('style'): st = copy.deepcopy( self.styles.table_styles[td.get('style')]) for s in st._cmds: s[1][1] = posy s[2][1] = posy s[1][0] = posx s[2][0] = posx styles.append(st) if td.get('paraStyle'): # TODO: merge styles paraStyle = self.styles.styles[td.get('paraStyle')] posx += 1 flow = [] for n in utils._child_get(td, self): if n.tag == etree.Comment: n.text = '' continue fl = self._flowable(n, extra_style=paraStyle) if isinstance(fl, list): flow += fl else: flow.append(fl) if not len(flow): flow = self._textual(td) data2.append(flow) if len(data2) > length: length = len(data2) for ab in data: while len(ab) < length: ab.append('') while len(data2) < length: data2.append('') data.append(data2) posy += 1 if node.get('colWidths'): assert length == len(node.get('colWidths').split(',')) colwidths = [ utils.unit_get(f.strip()) for f in node.get('colWidths').split(',') ] if node.get('rowHeights'): rowheights = [ utils.unit_get(f.strip()) for f in node.get('rowHeights').split(',') ] if len(rowheights) == 1: rowheights = rowheights[0] table = platypus.LongTable(data=data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'], { 'repeatRows': 'int', 'repeatCols': 'int' }))) if node.get('style'): table.setStyle(self.styles.table_styles[node.get('style')]) for s in styles: table.setStyle(s) return table
def font_size_get(self,tag): size = utils.unit_get(self.style.get('td', {}).get('font-size','16')) return size
def draw(self): self.canv.beginForm("pageCount%d" % self.story_count) self.canv.setFont("Helvetica", utils.unit_get(str(8))) self.canv.drawString(0, 0, str(self.canv.getPageNumber())) self.canv.endForm()
def _tag_spacer(self, node): length = 1+int(utils.unit_get(node.getAttribute('length')))/35 return "<br/>"*length
def _rect(self, node): if node.get('round'): self.canvas.roundRect(radius=utils.unit_get(node.get('round')), **utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'})) else: self.canvas.rect(**utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'}))