2013-09-27 10 views
0

我有下面的代碼嘗試從CSV文件創建字典,然後將CSV中每個「行」的值附加到PDF中的新頁面。我正在使用pyPdf和ReportLab來完成此操作。正在應用與字典相同的值

源PDF包含2頁,一個明信片的正面和背面,我試圖爲CSV文件中的每條記錄複製一張明信片。例如,一個包含25條記錄的CSV文件會導致一個包含50頁的PDF文件。 (每條記錄有一條正面和一條背面)

我已成功創建具有相應頁數的PDF,但是,我的代碼中用於附加CSV文件中的值的部分正在附加相同的每個頁面的值相同,而不是每頁的唯一值。

我很確定這與循環有關,因爲打印字典會正確返回所有的鍵和值對。我在這裏做錯了什麼?

d = {}       
csv_file = open(filename, 'rb') 
reader = csv.reader(csv_file) 
rownum = 0 
for row in reader: 
    total_rows += 1 
    page_count = (total_rows - 1) 
    if rownum == 0: 
     header = row 
    else: 
     colnum = 0 
     for col in row: 
      d[header[colnum]] = col 
      colnum += 1 

     packet = StringIO.StringIO() 

     can = canvas.Canvas(packet, pagesize=(621,405)) 
     can.drawString(340, 147, d['FirstName']) 
     can.save() 

     packet.seek(0) 
     new_pdf = PdfFileReader(packet)       

     existing_pdf = PdfFileReader(file(order, 'rb')) 
     output = PdfFileWriter() 

     front = existing_pdf.getPage(0) 
     back = existing_pdf.getPage(1) 
     back.mergePage(new_pdf.getPage(0)) 
     for i in range(0, page_count): 
      output.addPage(front) 
      output.addPage(back) 

     outputStream = file(token+'_merged.pdf', 'wb') 
     output.write(outputStream) 
     outputStream.close() 

    rownum += 1 
+0

哪裏'token'和'page_count'定義?它在我看來像是覆蓋CSV中每一行的多頁PDF。有一些地方可以清理一些代碼(查看'csv'模塊的'DictReader'類,內置的'enumerate'函數可以替代手動跟蹤rownum),但這些並不重要。 –

+0

@PeterDeGlopper'token'在代碼的前面定義,並且基於CSV文件的文件名。 'page_count'我完全忘了包含,我已經更新了上面的代碼,它現在在''閱讀器循環中的行中。我查看了'enumerate'選項,但是讀到它可能會佔用大量內存,所以我放棄了這一點。我可能會誤解,但... –

+0

請減少您的原始程序,以儘可能最短**完整**程序,演示錯誤。請參閱http://SSCCE.ORG瞭解爲什麼這會有所幫助。 –

回答

1

這個循環創建的CSV每行一個新的文件,重寫早先的行創建的版本。我不完全熟悉你使用的庫,但它看起來像移動outputStream的保存主循環外將解決這個問題的方法:

output = PdfFileWriter() 
for rownum, row in enumerate(reader): 
    if rownum == 0: 
     header = row 
    else: 
     for col in row: 
      d[header[colnum]] = col 
      colnum += 1 
     # or, more concisely: 
     # d = dict((header[colnum], value) for (colnum, value) in enumerate(row)) 
     # or use a dict comprehension if you're on a sufficiently recent version 
     # or best of all, use a csv.DictReader object instead of creating the dictionary yourself 

     packet = StringIO.StringIO() 

     can = canvas.Canvas(packet, pagesize=(621,405)) 
     can.drawString(340, 147, d['FirstName']) 
     can.save() 

     packet.seek(0) 
     new_pdf = PdfFileReader(packet)       

     # I would check whether this can be read once and still have getPage called multiple times 
     existing_pdf = PdfFileReader(file(order, 'rb')) 

     front = existing_pdf.getPage(0) 
     back = existing_pdf.getPage(1) 
     back.mergePage(new_pdf.getPage(0)) 
     output.addPage(front) 
     output.addPage(back) 

outputStream = file(token+'_merged.pdf', 'wb') 
output.write(outputStream) 
outputStream.close() 
+0

這很好,謝謝。我也接受了你的建議,並使用'csv.DictReader'來幫助清理我的代碼。 –