2012-01-22 43 views
2

我使用django和reportlab工具生成动态PDF报告。报告中的所有数据都来自数据库。Django和reportlab动态报告问题

我使用由来自数据库的数据组成的reportlab生成动态PDF报告。我的问题是每当我重新启动Apache服务器时,我的PDF报告数据正在改变。生成的报告使用Django查询来显示数据。但是,当我重新启动Apache服务器,然后正确的数据不会出现在报告中。

我检查了我在我的django视图中编写的所有查询。另外我注意到,Apache服务器的每次重启都显示不同的结果。所以我不这么认为这是我的django查询的问题。有没有解决这个问题的方法?

如果我重新启动apache服务器已经生成的报告的数据会改变,这个问题的原因是什么,有什么解决办法?

或者它是由于Apache服务器?

这里是源代码。我认为StringIO被错误地放置。

buffer = StringIO() 

def analysis_report(request, sample_no, contact_person): 

""" 
This function generates the analysis report by using the 
client information, transformer details, sample data and 
test results of respective analysis. 
""" 

response = HttpResponse(mimetype='application/pdf') 
response['Content-Disposition'] = 'attachment;filename=ANALYSIS_REPORT.pdf' 

doc = SimpleDocTemplate(buffer) 

document = [] 
doc.sample_no = sample_no 
doc.contact_person = contact_person 

image = Paragraph(stamp_image, STYLES['NORMAL_RIGHT']) 

document.append(image) 

# BUILTIN FUNCTION TO GENERATE THE DOCUMENT. 

doc.build(document, onLaterPages=header_footer) 

pdf = buffer.getvalue() 

response.write(pdf) 

return response 

在此先感谢

+0

你能解释一下你确切需要什么,并请用一些例子来支持。 –

+0

我们的生产箱有一个奇怪的问题,我希望有人能够说明一些问题。我们使用Reportlab和Django来 通过HTTP服务PDF。如果我们重新启动apache服务器,现有PDF报告的数据将发生变化,即使我们没有更改该报告。 – Asif

+0

你是如何在apache后面运行django的? fastCGI,wsgi?现有PDF的数据究竟意味着什么?你是否说在不重新生成报告的情况下重启Apache时缓存的PDF正在改变? – Meitham

回答

3

首先,你的情况是一个大问题可能是buffer = StringIO()是不是在功能范围,但你使用它的功能中。

我不确定你到底在做什么 - 你给我们的代码是整个工作PDF文件中最小的代码片段 - 但这里有一个来自一个只需要做2个真正巨大PDF的人的指针对于一个Django项目包:

  • 写一个类来创建和封装PDF文档对象
    • 第一个PDF文档我写保持在范围上成长 - 让所有视图的逻辑变得过分管理
    • 你的班级应该有一个功能来建立你的每个页面模板
    • 如果你的页面模板中使用回调onPage=每个那些回调也应该在你的类中单独定义
    • 数据应该有自己的功能(在我的案件的每一个独特的部分:第1页第2页和披露的各得了一个功能,因为他们的数据在逻辑上不同的块)

所以这里有一个例子views.py:

@check_requirments 
def pdf(request) : 
    """ 
    Download a PDF 
    """ 
    response = HttpResponse(mimetype='application/pdf') 
    response['Content-Disposition'] = 'attachment; filename=new.pdf' 

    pdf = MyPdf(response) 
    pdf.add_first_page() 
    pdf.add_second_page() 
    pdf.add_disclosures() 
    pdf.build() 

    return response 

和示例Ø ˚F我的PDF类:

# Page Setup 
PAGE_WIDTH, PAGE_HEIGHT = landscape(letter) 

class MyPdf(): 
    """ 
    My PDF 
    """ 
    document   = None 

    def __init__(self, file_like_handle=None): 
     self.document = BaseDocTemplate(file_like_handle, pagesize=landscape(letter)) 

     self.build_templates() 

    def build_templates(self): 

     first_page_frames = [] 

     #First Page Title Frame 
     frame_title = Frame(.25*inch, PAGE_HEIGHT-(1.75*inch), PAGE_WIDTH-(inch*.5), inch*.5, id="frame_title", showBoundary=0) 
     first_page_frames.append(frame_title) 

     # First Page Body Frames 
     frame_body = Frame(.5*inch, PAGE_HEIGHT-(8*inch), PAGE_WIDTH-(inch), inch*6.25, id="frame_body", showBoundary=0) 
     first_page_frames.append(frame_body) 

     # Second Page Body Frame 
     frame_body_full = Frame(.5*inch, PAGE_HEIGHT-(8*inch), PAGE_WIDTH-(inch), inch*7, id="frame_body_full", showBoundary=0) 

     templates = [] 
     templates.append(PageTemplate(frames=first_page_frames, id="first_page", onPage=self.first_page)) 
     templates.append(PageTemplate(frames=[frame_body_full], id="child_pages", onPage=self.child_pages)) 
     templates.append(PageTemplate(frames=[frame_body_full], id="child_pages", onPage=self.last_page)) 
     self.document.addPageTemplates(templates) 


    def first_page(self, canvas, doc): 
     """ 
     First page has an image header and footer 
     """ 
     canvas.saveState() 
     canvas.drawInlineImage(settings.MEDIA_ROOT + "../static/pdf-header-landscape.png", inch*.25, PAGE_HEIGHT-(1.25 * inch), PAGE_WIDTH-(.5*inch), ((11/8)*inch)) 
     canvas.drawInlineImage(settings.MEDIA_ROOT + "../static/pdf-footer-landscape.png", inch*.25, inch*.25, PAGE_WIDTH-(.5*inch), (.316*inch)) 
     canvas.restoreState() 


    def child_pages(self, canvas, doc): 
     """ 
     Second page has a smaller header and the same footer 
     """ 
     canvas.saveState() 
     canvas.setFillColor(HexColor("#f4f3f1")) 
     canvas.rect(inch*.25, PAGE_HEIGHT-(.25 * inch), PAGE_WIDTH-(.5*inch), -(.5*inch), fill=1, stroke=0) 
     canvas.setFillColor(HexColor("#e5b53b")) 
     canvas.setFont('Gotham-Bold', 16) 
     canvas.drawString(inch*.5, PAGE_HEIGHT-((.6)*inch), "PAGE") 
     canvas.setFillColor(HexColor("#00355f")) 
     canvas.drawString(inch*1.75, PAGE_HEIGHT-((.6)*inch), "OVERVIEW") 
     canvas.drawInlineImage(settings.MEDIA_ROOT + "../static/pdf-footer-landscape.png", inch*.25, inch*.25, PAGE_WIDTH-(.5*inch), (.316*inch)) 
     canvas.restoreState() 


    def build(self): 
     return self.document.build(self.elements) 


    def add_first_page(self): 

     sample = getSampleStyleSheet() 
     style_title = copy.deepcopy(sample['BodyText']) 
     style_title.fontSize = 18 
     style_title.textColor = HexColor("#00355f") 

     style_body = copy.deepcopy(sample['BodyText']) 
     style_body.fontSize = 10 
     style_body.alignment = reportlab.lib.enums.TA_LEFT 
     style_body.spaceBefore = 25 
     style_body.spaceAfter = 15 
     style_body.textColor = HexColor("#000000") 
     style_body.leading = 14 

     self.elements.append(Paragraph("""<font color="#e5b53b">PAGE</font>OVERVIEW""", style_title)) 
     self.elements.append(FrameBreak()) 

     self.elements.append(Paragraph("""Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean elementum malesuada euismod. Praesent ut ante risus. Aenean eleifend massa elit, non adipiscing ipsum. Integer et arcu tortor, a bibendum metus. Maecenas eget nulla id sem placerat dignissim sit amet et ligula. Donec vitae mi mauris. Praesent lacinia, mauris at malesuada bibendum, metus eros molestie ipsum, sed consequat dolor diam interdum ipsum. Phasellus consectetur auctor laoreet. Suspendisse vel nisl lacus, vitae auctor dui.""", style_body)) 

     # ADD A CUSTOM REPORTLAB CANVAS OBJECT 
     self.elements.append(SomeGraph()) 

     self.elements.append(Paragraph("""Our strategic allocations for each strategy are determined by our Dynamic Strategic Asset Allocation process - the Science of Dynamic Investing. Our proprietary mathematical model uses updated Price Matters<super>&reg;</super> capital market assumptions (expected return, risk and correlation figures) to determine the optimal allocation to each asset class to achieve the goals of each strategy within the assigned risk tolerance and time horizon. The Art of Dynamic Investing enables us to adapt to changing economic and political realities as we reposition strategies with tactical tilts to the strategic allocations as we see value and momentum of various asset classes being affected during the year. <font color="#e5b53b">The chart below</font> shows the strategic weightings and the tactical allocations to each asset class as of the close of business on the date cited.""", style_body)) 

     self.elements.append(NextPageTemplate("child_pages")) 
     self.elements.append(PageBreak())  

    def add_second_page(self): 
     sample = getSampleStyleSheet() 
     style_title = copy.deepcopy(sample['BodyText']) 
     style_title.fontSize = 18 
     style_title.textColor = HexColor("#00355f") 

     style_body = copy.deepcopy(sample['BodyText']) 
     style_body.fontSize = 10 
     style_body.alignment = reportlab.lib.enums.TA_LEFT 
     style_body.spaceBefore = 25 
     style_body.spaceAfter = 15 
     style_body.textColor = HexColor("#000000") 
     style_body.leading = 14 

     self.elements.append(Paragraph("""Morbi posuere erat non nunc faucibus rhoncus. Donec at ante at tellus vehicula gravida. Praesent vulputate viverra neque, ut consectetur turpis vestibulum at. Integer interdum diam sed leo vehicula in viverra mauris venenatis. Morbi tristique pretium nunc vel ultrices. Fusce vitae augue lorem, et feugiat lorem. Donec sit amet nulla eget elit feugiat euismod rutrum ut magna. Pellentesque condimentum, tellus at rutrum egestas, dui neque dapibus risus, malesuada mollis risus eros id ligula. Fusce id cursus nulla. Etiam porttitor vulputate tellus eu blandit. Donec elementum erat sed tellus dapibus eleifend. Pellentesque sagittis, libero ac sodales laoreet, erat turpis fringilla est, vel accumsan nunc nisi eget orci. Integer condimentum libero in tellus lacinia ultricies quis ac odio. Vivamus justo urna, faucibus vitae bibendum dapibus, condimentum et ligula. Nullam interdum velit at orci blandit nec suscipit lorem lobortis. Pellentesque purus nunc, pulvinar vitae ullamcorper id, rhoncus sit amet diam.""", style_body)) 

    def add_disclosures(self): 

     sample = getSampleStyleSheet() 
     style_d = copy.deepcopy(sample['BodyText']) 
     style_d.fontSize  = 8 
     style_d.alignment = reportlab.lib.enums.TA_LEFT 
     style_d.textColor = HexColor("#9D8D85") 

     self.elements.append(NextPageTemplate("last_page")) 
     self.elements.append(PageBreak()) 

     self.elements.append(Paragraph("""Important Disclosures""", style_d)) 

     self.elements.append(Paragraph("""Copyright 2012 Francis Yaconiello All Rights Reserved.""", style_d)) 

注:我没有测试过这个类,因为它是,我基本上抓住了大量的专用信息指出,我已经有一类和削减下来,便于消化。这意味着让您了解如何将PDF设置为最佳做法。

+0

我在解决问题的函数中保存了** buffer = StringIO()**。非常感谢 – Asif

+0

@Sahil,如果它是正确的,你可以将其标记为解决方案吗? –