2012-01-22 42 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,如果它是正確的,你可以將其標記爲解決方案嗎? –