Pandas DataFrames in reportlab

Charles Dillon picture Charles Dillon · Jul 9, 2013 · Viewed 8.1k times · Source

I have a DataFrame, and want to output it to a pdf. I'm currently trying to use ReportLab for this, but it won't seem to work. I get an error here:

        mytable = Table(make_pivot_table(data, pivot_cols, column_order, 'criterion'))

make_pivot_table just returns a pivot table using pandas pivot_table function. The error I get is

ValueError: <Table@0x13D7D0F8 unknown rows x unknown cols>... invalid data type

My questions are:

  1. Is there any way to make reportlab work with DataFrames?
  2. If not, what package can I use for the same purpose?

Answer

Fabio Pomi picture Fabio Pomi · Jul 15, 2013

Py

Hallo,

I'm also needing to print as .pdf some Pandas DataFrame to arrange reports. I tried ReportLab directly with df and had an "AttributeError: 'DataFrame' object has no attribute 'split'." I tried with df.values() and had "TypeError: 'numpy.ndarray' object is not callable".

When close to quit the idea to build the .pdf report I tried str(df) and I had some outcome in the .pdf :-) ... The code looks like:

import pandas as pd
from reportlab.pdfgen import canvas
PATH_OUT = "C:\\"
def pdf_df(c, testo, x, y):
    c.drawAlignedString(x,y, testo)
df = pd.DataFrame({'a':[3,4,5], 'b':[6,7,6],'c':[9,10,11]})
print df, type(df)
print''
df1 = (df['a'].groupby([df['b'], df['a']])).sum()
print df1, type(df1)
print ''
c = canvas.Canvas(PATH_OUT + 'out.pdf')
pdf_df (c, str(df), 300, 500)
pdf_df (c, str(df1), 300, 480)
c.showPage()
c.save()  

What do you think ? Might this make sense or there might be some 'smarter' way?

This one seems not so effcient and I initially hoped to have from ReportLab. It seems I'd need then some way to wrap the lines .. and sizes will change ...

Fabio

=====

I'm now much happier of the below solution, while I was not happy about the above one too.

This is based on ReportLab grids, they work on lists. So the code is converting DF to list which is then treated as a ReportLab grid :-)

Here it is:

from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import *
from reportlab.lib import colors
import pandas as pd
import random

PATH_OUT = "C:\\"

elements = []
styles = getSampleStyleSheet()
doc = SimpleDocTemplate(PATH_OUT + 'Report_File.pdf')
elements.append(Paragraph("Report Title", styles['Title']))

data = [[random.random() for i in range(1,4)] for j in range (1,8)]
df = pd.DataFrame (data)
lista = [df.columns[:,].values.astype(str).tolist()] + df.values.tolist()

ts = [('ALIGN', (1,1), (-1,-1), 'CENTER'),
     ('LINEABOVE', (0,0), (-1,0), 1, colors.purple),
     ('LINEBELOW', (0,0), (-1,0), 1, colors.purple),
     ('FONT', (0,0), (-1,0), 'Times-Bold'),
     ('LINEABOVE', (0,-1), (-1,-1), 1, colors.purple),
     ('LINEBELOW', (0,-1), (-1,-1), 0.5, colors.purple, 1, None, None, 4,1),
     ('LINEBELOW', (0,-1), (-1,-1), 1, colors.red),
     ('FONT', (0,-1), (-1,-1), 'Times-Bold'),
     ('BACKGROUND',(1,1),(-2,-2),colors.green),
     ('TEXTCOLOR',(0,0),(1,-1),colors.red)]

table = Table(lista, style=ts)
elements.append(table)

doc.build(elements)

I'm really interested to read about other possible solutions ..

Bye, Fabio.