Ticket #71 (closed New feature: fixed)
Plugin to provide PDF export of data
| Reported by: | matt | Owned by: | |
|---|---|---|---|
| Priority: | critical | Milestone: | Piwik 0.7 - DigitalVibes |
| Component: | New Plugin | Keywords: | |
| Cc: | Sensitive: | no |
Description (last modified by matt) (diff)
Users need to share Piwik reports with colleagues, customers or externals. PDF is the standard way of exchanging rich data, with graphs, colors, consistent design.
Proposed features set of Piwik PDF export
For the first release of PDF export in Piwik, I think the following features would be important to have:
- Create the pdf: the PDF would not be customizable and would include all Piwik reports. The tables would be "all columns" tables, ie. they contain Visits, unique visitors, bounce rate, goal conversion rate, etc.
- Send & receive the PDF: the PDF would be downloadable via a click in the "User Settings" page. Also, a click on a link would send an email with the PDF attached to the given email addresses (easier for users to forward the emails to others rather than create a new email, attaching the PDF, etc.).
- Look and feel: the PDF reports would contain tables, that look similar to the tables in Piwik reports. For example, search engine icons, countries flags would be displayed. Each page would contain the title of the report, and as many rows as can fit on the page (maybe 20 rows per table?).
- Internationalization. The PDF reports would be localized in any of the 35+ languages.
Other features probably for later releases:
- Customize PDF: each user would be able to customize which reports make it in the PDF. Possibility to create several PDF reports, per website, or for a given website.
- Receive the PDF by email: using a new hook, see #1184, the PDF reports plugin could automatically generate and send PDF reports by email to each user that requested delivery. Users could customize the frequency (daily, weekly, monthly), and recipients (themselves and others) to send the PDF reports to.
- PDF contains sparklines
- Each Piwik widget/report can be exported in PDF (add a new export link below the table, next to CSV, XML, etc.).
Features currently not considered
- PDF contains graphs: bar, pie, evolution charts. Graphs export in PDF would be a major maintenance / time intensive task, as we would have to support a second graphing library, as OFC is flash based and can't generate PNGs.
Thoughts about implementation
Here are some thoughts about the implementation. Please discuss before implementing, there might be better solutions.
API to render PDF
Rendering a PDF could then be done by using following call:
module=API& method=PDF.getReport& report=$REPORT_ID& idSite=$WEBSITE_ID& token_auth=$TOKEN& date=...&period=...
In V1, when customReports are not implemented, we would have a function PDF.getFullWebsiteReport which would return the PDF containing all reports for a given website.
There could also be a PDF.getWebsitesDashboard which would return a simple PDF containing main metrics for all websites visible to the user.
Flow of a request to generate a PDF containing all reports
When called, the PDF API function would then:
- create and setup as default the PDF view.
- init the PDF: set colors, margins, titles, properties, generated time, etc.
- loop over all controllers, and methods that we wish to render.
- call the methods in each plugin's controller which add data to the PDF. All methods would render the "all columns" data table (that shows visits, pages, time per visit, etc.) rather than just the simple table with only the visits column.
- render the final PDF and output it to the browser
Basic skeleton for the API method PDF.getReport
function getReport($report, $idSite, $date, $period)
{
// set the default View to PDF Piwik_View::setDefaultView(new Piwik_View_PDF());
// define an array of Controllers/methods to call to render in this PDF,
// eg. array( array( 'Goals', 'index'), array('UserSettings', 'getBrowser') )
// loop over all the array of methods to render
// here we could add a new page, a pdf page title for the next report, etc.
// for each controller method, call it, for example
$content = Piwik_FrontController::getInstance()->fetchDispatch( 'Goals', 'index');
// this will call the index() on Goals/Controller.php
// which will, at the end, render the view eg. $view->getView()->render()
// this will result in Piwik_View_PDF->render() call which adds the right data to the PDF file being built.
// once all reports have been added to PDF, return PDF to the user
}
A new View type
Currently in plugins Controllers, views are created with:
$view = new Piwik_View('Goals/templates/single_goal.tpl');
The view object encapsulates the Smarty implementation. Variables are set to the view $view->name = $goalDefinition['name']; and the view is rendered at the end of the controller method: echo $view->render();
In order to add PDF export with minimal effort, PDF could be a new View class, implementing the iView interface.
Currently there is core/View.php which should probably be moved to core/View/Smarty.php
there is some generic code in render() which could probably be left in the new core/View.php parent object.
We could have Piwik_View_Smarty extends Piwik_View then we would build Piwik_View_PDF extends Piwik_View
When building a PDF report, each controller's method would be called, and the data would be added to the PDF report hold in this object. The report builder API would then output this aggregated PDF to the user.
Adding renderer
Piwik_View_PDF could look at the template name passed in the view constructor, and based on this find out if it knows how to render this template. For example, calling the Goals.goalReport method (in plugins/Goals/Controller.php), the View is using the template Goals/templates/single_goal.tpl - if the view does know how to render this (given the variables are set properly like on the smarty template), then it can render it. If not, an error can be output. The PDF view would have logic that says: "Goals/templates/single_goal" must be rendered this way. Most templates are generic (datatable, etc.) so most of the work to render the reports would be done only once and automatically work for most reports.
Rendering text, tables in the PDF
The library might support automatic conversion of HTML into the PDF, but most likely this doesn't work very well. We will most likely have to write a basic PDF renderer for the datatable (equivalent of datatable.tpl).
Custom reports
By default, we can include all tables in the PDF. But reports are useful only if they contain the subset of information a given user is interested in. We could have a simple UI, listing all available reports, with a click and add to report feature. This would be internally linked to calls to controller methods. The layout could be saved as JSON in the reports table.
UI integration
PDF reports do not apply on per report basis, like Bar graphs or Pie charts apply. There could be a link to generate a PDF report for the current website in the header.
Contributions
Interested by this feature? Let us know in the comments.

