At least the Mako reports should be flexible enough for your needs. With them you can create HTML tables and use for loops to format the rows and columns to fit your dataset. Even though you're working with HTML and CSS to format and style the data, the result will still be a PDF file.
If you want to see a basic example of how the Mako reports work, you can download a very nice module called sale_order_webkit, it's made by camptocamp and is available at v6apps.openerp.com/addon/6581
The example deals with pulling data from a single model, but if you're working with a complex dataset and need data from many tables, you can also directly query the database with cr.execute and pass the result to be formatted with Mako. We tried this direct query approach with some timesheet-related data and it worked very well.
Edit: here's a small code snippet from a .mako file
<table>
<tr>
% for key,value in month_data(emp_id).iteritems():
<td>
${value}
</td>
% endfor
</tr>
</table>
-emp_id and month_data are attached to the report parser on the fly with self.localcontext.update(), after which they are accessible by the .mako template
class TimesheetReportParser(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(TimesheetReportParser, self).__init__(cr, uid, name, context=context)
emp_id = context['active_id']
self.localcontext.update({
'emp_id': emp_id,
'month_data': self._fetch_hours,
})
-emp_id is the employee ID of the person whose timesheet report is currently being generated
-month_data's contents are provided by a _fetch_hours() function that is also defined inside the parser class, it does a cr.execute() and returns a dictionary of values related to the current employee. Those values are then printed out in a for loop in the .mako file