Wt provides two classes for rendering to PDF:
The class WPdfImage is a paint device for rendering to PDF. It supports two main use-cases:
A WPdfImage
paint device is typically used in
conjunction with a WPainter, which provides a
high-level unified painting API.
The PDF is generated using
The Haru Free PDF Library. This class
is included in the library only if libharu
was found during the
build of the library.
The following example shows how to use a WPdfImage
directly in
conjunction with WPainter
.
Another common use-case is to paint the contents of a
WPaintedWidget
, such as a chart, to a PDF :
#include <Wt/Chart/WCartesianChart.h>
#include <Wt/WPdfImage.h>
auto chart = std::make_unique<Chart::WCartesianChart>();
WPdfImage pdfImage("4cm", "3cm");
{
WPainter p(&pdfImage);
chart->paint(p);
}
std::ofstream f("chart.pdf", std::ios::out | std::ios::binary);
pdfImage.write(f);
When you want to embed a PDF image into a larger document, you need to use its constructor which passes an existing PDF document and page for it to paint on. This approach is used for example by the WPdfRenderer to render XHTML to multi-page PDF files.
Font information is embedded in the PDF. Fonts supported are native
PostScript fonts (Base-14) (only ASCII-7), or true type fonts
(Unicode). See addFontCollection()
for more information on how
fonts are located and matched to WFont descriptions.
The paint device has the following limitations:
WPainter::drawImage()
) can only be included
from local files, and only JPG or PNG images can be embedded.
The class WPdfRenderer implements an XHTML to PDF renderer. It can be used to create multipage reports, without the need for programming tedious lay outing using a low-level drawing API.
The rendering engine supports only a subset of XHTML. See the documentation of WTextRenderer for more information.
Although the rendering class itself can render to any
WPaintDevice
(with font metrics), by far the most common
use-case is to render to a PDF document using
WPdfImage
. Typically, you will want to adapt the pixel
resolution By default it uses a pixel resolution of 72 DPI,
which is a common default for printed documents, but differs
from the default used by most browsers (which is 96 DPI and has
nothing to do with the actual screen resolution). The resolution
can be changed using setDpi()
and has the effect of
scaling down (or up) the rendering. This can be used in
conjunction with setFontScale()
to scale the font size
differently than other content.
This could be a big deal to your project, since this modest renderer does support many things commonly needed to render reports, such as:
Unordered lists:The renderer has fairly complete support for layout of floats (like images), including nested floats and their interactions with other inline and block contents.
There is obvious support for colors, different font sizes - big and small - and other fonts; including support for true type fonts.
You can attach an external style sheet, highlighting items that need special attention.
Reports typically contain tables, and these are also well supported; including multi-page ones, with automatic repetition of table headers.
FirstName | LastName | Company | Address | City | County | State |
---|---|---|---|---|---|---|
Essie | Vaill | Litronic Industries | 14225 Hancock Dr | Anchorage | Anchorage | AK |
Cruz | Roudabush | Meridian Products | 2202 S Central Ave | Phoenix | Maricopa | AZ |
Billie | Tinnes | D & M Plywood Inc | 28 W 27th St | New York | New York | NY |
Zackary | Mockus | Metropolitan Elevator Co | 286 State St | Perth Amboy | Middlesex | NJ |
Rosemarie | Fifield | Technology Services | 3131 N Nimitz Hwy | Honolulu | Honolulu | HI |
Bernard | Laboy | Century 21 Keewaydin Prop | 22661 S Frontage Rd | Channahon | Will | IL |
Sue | Haakinson | Kim Peacock Beringhause | 9617 N Metro Pky W | Phoenix | Maricopa | AZ |
Valerie | Pou | Sea Port Record One Stop Inc | 7475 Hamilton Blvd | Trexlertown | Lehigh | PA |
Lashawn | Hasty | Kpff Consulting Engineers | 815 S Glendora Ave | West Covina | Los Angeles | CA |
Marianne | Earman | Albers Technologies Corp | 6220 S Orange Blossom Trl | Orlando | Orange | FL |
Justina | Dragaj | Uchner, David D Esq | 2552 Poplar Ave | Memphis | Shelby | TN |
Mandy | Mcdonnell | Southern Vermont Surveys | 343 Bush St Se | Salem | Marion | OR |
Conrad | Lanfear | Kahler, Karen T Esq | 49 Roche Way | Youngstown | Mahoning | OH |
Cyril | Behen | National Paper & Envelope Corp | 1650 S Harbor Blvd | Anaheim | Orange | CA |
Shelley | Groden | Norton, Robert L Esq | 110 Broadway St | San Antonio | Bexar | TX |
Rosalind | Krenzke | Waldein Manufacturing | 7000 Bass Lake Rd | Minneapolis | Hennepin | MN |
Davis | Brevard | Transit Trading Corp | 6715 Tippecanoe Rd | Canfield | Mahoning | OH |
Winnie | Reich | Pacific Seating Co | 1535 Hawkins Blvd | El Paso | El Paso | TX |
Trudy | Worlds | Shapiro, Mark R Esq | 24907 Tibbitts Avenue | Valencia | Los Angeles | CA |
Deshawn | Inafuku | Telair Div Of Teleflex Inc | 3508 Leopard St | Corpus Christi | Nueces | TX |
Claudio | Loose | Audiotek Electronics | 286 State St | Perth Amboy | Middlesex | NJ |
Sal | Pindell | Wrigley, Robert I Esq | 1112 Se 1st St | Evansville | Vanderburgh | IN |
Cristina | Sharper | Tax Office | 111 W 40th St | New York | New York | NY |
Cary | Mccamey | Williams Scotsman | 100 E Broad St | Columbus | Franklin | OH |
Haley | Rocheford | Davis, Robert L Esq | 6030 Greenwood Plaza Blvd | Englewood | Arapahoe | CO |
Dorothea | Sweem | Ehrmann, Rolfe F Esq | 100 Thanet Circ | Trenton | Mercer | NJ |
Fannie | Steese | Chiapete, W Richard Esq | 926 E ParkAve | Tallahassee | Leon | FL |
Allyson | Gillispie | De Friese Theo & Sons | 1722 White Horse Mercerville R | Trenton | Mercer | NJ |
Roger | Seid | Yoshida, Gerald C Esq | 3738 N Monroe St | Tallahassee | Leon | FL |
Dollie | Daquino | Jd Edwards & Co | 1005 Congress Ave | Austin | Travis | TX |
Eva | Seahorn | Saunders Appraisal Inc | 3 Northern Blvd | Amherst | Hillsborough | NH |
Mamie | Mcintee | Jacobs, Brian Realtor | 2810 Jacobs Ave | Eureka | Humboldt | CA |
Lashonda | Derouen | Travel Agent Magazine | 101 Royal St | Alexandria | Alexandria City | VA |
Jacklyn | Emayo | Super 8 Motel Temple | 101 Us Highway 46 | Fairfield | Essex | NJ |
So, keep it in mind !
#include <Wt/WPushButton.h>
#include <Wt/WResource.h>
#include <Wt/Http/Request.h>
#include <Wt/Http/Response.h>
#include <Wt/Render/WPdfRenderer.h>
#include <Wt/WApplication.h>
#include <hpdf.h>
#include <hpdf_version.h>
namespace {
void HPDF_STDCALL error_handler(HPDF_STATUS error_no,
HPDF_STATUS detail_no,
void *user_data) {
auto pdfImage = static_cast<Wt::WPdfImage*>(user_data);
pdfImage->errorHandler(error_no, detail_no);
}
}
class ReportResource : public Wt::WResource
{
public:
ReportResource()
: WResource()
{
suggestFileName("report.pdf");
}
virtual ~ReportResource()
{
beingDeleted();
}
virtual void handleRequest(const Wt::Http::Request& request,
Wt::Http::Response& response)
{
response.setMimeType("application/pdf");
HPDF_Doc pdf = HPDF_New(error_handler, 0);
// Note: UTF-8 encoding (for TrueType fonts) is only available since libharu 2.3.0 !
HPDF_UseUTFEncodings(pdf);
renderReport(pdf);
HPDF_SaveToStream(pdf);
unsigned int size = HPDF_GetStreamSize(pdf);
HPDF_BYTE *buf = new HPDF_BYTE[size];
HPDF_ReadFromStream (pdf, buf, &size);
HPDF_Free(pdf);
response.out().write((char*)buf, size);
delete[] buf;
}
private:
void renderReport(HPDF_Doc pdf) {
renderPdf(Wt::WString::tr("report.example"), pdf);
}
void renderPdf(const Wt::WString& html, HPDF_Doc pdf)
{
HPDF_Page page = HPDF_AddPage(pdf);
HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
Wt::Render::WPdfRenderer renderer(pdf, page);
renderer.setMargin(2.54);
renderer.setDpi(96);
renderer.render(html);
}
};
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WText *text = container->addNew<Wt::WText>(Wt::WString::tr("report.example"));
text->setStyleClass("reset");
Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Create pdf");
auto pdf = std::make_shared<ReportResource>();
button->setLink(Wt::WLink(pdf));