2010-03-18 19 views
7

Bu küçük Django görünümünü pdf döndürmek için yazdım.Django ve Reportlab Soru

@login_required 
def code_view(request,myid): 
    try: 
     deal = Deal.objects.get(id=myid) 
    except: 
     raise Http404 
    header = deal.header 
    code = deal.code 
    response = HttpResponse(mimetype='application/pdf') 
    response['Content-Disposition'] = 'attachment; filename=code.pdf' 
    p = canvas.Canvas(response) 
    p.drawString(10, 800, header) 
    p.drawString(10, 700, code) 
    p.showPage() 
    p.save() 
    return response 

Ve sorularım:

  • Utf-8 karakterleri doğru PDF içinde gösterilmemiştir.
  • Bir resmi nasıl ekleyebilirim?

:

  • nasıl gibi bir çok temel html içerebilir.

    <ul> 
        <li>List One</li> 
        <li>List Two</li> 
        <li>List Three</li> 
    </ul> 
    
  • cevap

    2

    Reportlab bazı temel HTML biçimlendirme (<b>, <i>), bu listeleri yapabilir emin değil işleyebilir. HTML'den PDF'ye dönüştürme için pisa'u kullanabilirsiniz. Daha sonra görüntü eklenmesi için <img> etiketini de kullanabilirsiniz (görüntüyü kullanmak için PIL'u yüklemeniz gerekir)

    10

    Bir sonraki seviyeye geçmeli ve DocTemplates'i kullanmalısınız. Resimler oldukça kolay, ancak mermi kullanmak gerçekten zor - stilleri ve daha fazlasını tanımlamanız gerekiyor!

    aşağıda gibi sınıflar kümesi kullanın:

    # -*- coding: utf-8 -*- 
    
    from django.utils.encoding import smart_str 
    from reportlab.lib.colors import Color 
    from reportlab.lib.pagesizes import A4 
    from reportlab.lib.styles import StyleSheet1, ParagraphStyle 
    from reportlab.lib.units import cm 
    from reportlab.pdfgen import canvas 
    from reportlab.platypus.doctemplate import BaseDocTemplate, PageTemplate, \ 
        _doNothing 
    from reportlab.platypus.frames import Frame 
    from reportlab.platypus.paragraph import Paragraph 
    import copy 
    import re 
    from reportlab.platypus.flowables import KeepTogether, Image, PageBreak 
    from htmlentitydefs import name2codepoint 
    from atom.http_core import HttpResponse 
    import tempfile 
    
    def htmlentitydecode(s): 
        return re.sub('&(%s);' % '|'.join(name2codepoint), lambda m: smart_str(unichr(name2codepoint[m.group(1)])), s) 
    
    PS = ParagraphStyle 
    stylesheet = StyleSheet1() 
    
    stylesheet.add(PS(name='Normal', 
            leading=15)) 
    stylesheet.add(PS(name='Bullet', 
            parent=stylesheet['Normal'], 
            bulletFontName = 'Symbol', 
            bulletIndent = 0, 
            bulletFontSize = 13, 
            bulletColor = Color(0.93,0,0), 
            bulletOffsetY = -1.5, 
            leftIndent = 15.8, 
            firstLineIndent = 0, 
           ), alias='bu') 
    stylesheet.add(PS(name='Heading1', 
            parent=stylesheet['Normal'], 
            fontSize=18, 
            spaceAfter=23.5), alias='h1') 
    stylesheet.add(PS(name='Heading2', 
            parent=stylesheet['Normal'], 
            fontSize=14, 
            spaceAfter=4), alias='h2') 
    stylesheet.add(PS(name='Heading3', 
            parent=stylesheet['Normal'], 
            textColor=Color(0.93,0,0) 
           ), alias='h3') 
    stylesheet.add(PS(name='Heading4', 
            parent=stylesheet['Heading3'], 
            textColor='black'), alias='h4') 
    
    BulletStyle = copy.deepcopy(stylesheet["Bullet"]) 
    H1Style = copy.deepcopy(stylesheet["Heading1"]) 
    H2Style = copy.deepcopy(stylesheet["Heading2"]) 
    H3Style = copy.deepcopy(stylesheet["Heading3"]) 
    H4Style = copy.deepcopy(stylesheet["Heading4"]) 
    NormalStyle = copy.deepcopy(stylesheet["Normal"]) 
    
    top_margin = A4[1] - 1.22*cm 
    bottom_margin = 1.5*cm 
    left_margin = 2.8*cm 
    frame_width = 17.02*cm 
    
    right_margin = left_margin + frame_width 
    frame_height = 22.7*cm 
    
    letter_top_margin = 25.0*cm 
    letter_bottom_margin = 3.0*cm 
    letter_left_margin = 2.5*cm 
    letter_right_margin = A4[0] - 2.5*cm 
    letter_frame_width = A4[0] - 5.0*cm 
    letter_frame_height = letter_top_margin - letter_bottom_margin 
    
    
    class LetterTemplate(BaseDocTemplate): 
        _invalidInitArgs = ('pageTemplates',) 
    
        def handle_pageBegin(self): 
         self._handle_pageBegin() 
         self._handle_nextPageTemplate('First') 
    
        def build(self, flowables, onFirstPage=_doNothing, canvasmaker=canvas.Canvas): 
         self._calc() 
    
         frameT = Frame(letter_left_margin, letter_bottom_margin, letter_frame_width, letter_frame_height, 
             leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, 
             id='normal') 
    
         self.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=onFirstPage, pagesize=self.pagesize)]) 
    
         if onFirstPage is _doNothing and hasattr(self,'onFirstPage'): 
          self.pageTemplates[0].beforeDrawPage = self.onFirstPage 
    
         BaseDocTemplate.build(self, flowables, canvasmaker=canvasmaker) 
    
    
    class PdfA4Letter(object): 
    
        def __init__(self, filename): 
         self.title = filename 
         self._keep_together = False 
         self.elements = [] 
         self._keep_together_elements = [] 
         self.doc = LetterTemplate(filename,showBoundary=False) 
         self.elements = [] 
    
        def _process_text(self, txt): 
         text_elems = [] 
    
         # avoid us from user added html. 
         txt = txt.replace('&lt;','&lang;').replace('&gt;','&rang;') 
         txt = htmlentitydecode(smart_str(txt).replace('<p>', '').replace('</p>', '<br />')) 
    
         # @todo: in some case the reegxp does not work -> hack 
         txt = txt.replace('target="_blank"', '') 
         # process text 
         for part in re.split('<ul>|</ul>|<ol>|</ol>', txt): 
          part = part.strip() 
          if part.count('<li>') > 0: 
           for item in re.split('<li>|</li>', part): 
            item = item.strip() 
            if len(item) > 0: 
             text_elems.append(Paragraph(item, BulletStyle, bulletText=u'•')) 
          else: 
           text_elems.append(Paragraph(part, NormalStyle)) 
         return text_elems 
    
        def _store_flowable(self, flowable):   
         if self._keep_together == False: 
          self.elements.append(flowable) 
         else: 
          self._keep_together_elements.append(flowable) 
    
        def start_keep_together(self): 
         self.end_keep_together() 
         self._keep_together = True 
    
        def end_keep_together(self): 
         self._keep_together = False 
         if len(self._keep_together_elements) > 0: 
          e = self._keep_together_elements 
          self.elements.append(KeepTogether(e)) 
          self._keep_together_elements = [] 
    
        def newPage(self): 
         self._store_flowable(PageBreak()) 
    
        def blankline(self, cnt=1): 
         self.text(cnt*'<br/>') 
    
        def text(self, txt): 
         for e in self._process_text(txt): 
          self._store_flowable(e)   
    
        def image(self, name, width, height, halign='CENTER'): 
         im = Image(name, width=width, height=height) 
         im.hAlign = halign 
         self._store_flowable(im) 
    
        def h1(self, txt, add_to_toc=True): 
         self.newPage() 
         self._store_flowable(Paragraph(txt, H1Style)) 
    
        def h2(self, txt, add_to_toc=True): 
         self._store_flowable(Paragraph(txt, H2Style)) 
    
        def h3(self, txt, add_to_toc=False): 
         self._store_flowable(Paragraph(txt, H3Style)) 
    
        def h4(self, txt, add_to_toc=False): 
         self._store_flowable(Paragraph(txt, H4Style)) 
    
        def _drawPage(self, canvas, doc): 
         canvas.setSubject('Letter Subject') 
         canvas.setTitle('Letter Title') 
         canvas.setAuthor('Me') 
    
        def build(self): 
         # flush elems 
         self.end_keep_together() 
         self.doc.build(self.elements, self._drawPage) 
    

    Daha sonra, bu gibi, görünümünde pdf nesil kaldırabileceğinden:

    def view(request): 
    
        file = tempfile.NamedTemporaryFile() 
    
        e = PdfA4Letter(file.name) 
    
        ref = '/absolute/path/to/image.png' 
        e.image(ref, width=frame_width, height=10*cm) 
        e.h1((u'Über Mich')) 
        e.h3('Next header') 
    
        t = """ 
        ascasc<br /> 
        ascascasc<br /> 
        <ul> 
         <li>sdv1</li> 
         <li>sdv2</li> 
         <li>sdv3</li> 
        </ul> 
        ascasc<br /> 
        ascasc<br /> 
        """ 
    
        e.text(t) 
        e.blankline(2) 
        e.end_keep_together() 
        e.build() 
    
        response = HttpResponse(mimetype='application/pdf') 
        response['Content-Disposition'] = 'attachment; filename=gugus.pdf' 
        response.write(file.read()) 
        file.close() 
        return response  
    
    İlgili konular