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:
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.