Handling PDF

From Qt Wiki
Revision as of 15:38, 14 January 2015 by Maintenance script (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Handling PDF

This page discusses various available options for working with Portable Document Format (PDF) [en.wikipedia.org] documents in your Qt application. Please also read the general considerations outlined on the Handling Document Formats page.

Note that this information is collaboratively collected by the community, with no promise of completeness or correctness. In particular, use your own research and judgment when evaluating third-party libraries or tools!

Reading / Writing

Using QPrinter

  • manual QPainter painting
    The most basic (but not necessarily simplest) way of creating PDF documents with QPrinter is by manually painting the document’s content with Qt’s Arthur paint system.
    Just pass the QPrinter object as a reference to the constructor of QPainter (or, alternatively, to QPainter::begin for an already existing QPainter) and then perform any painting operations with that QPainter instance like you usually would (with intermittent calls to QPrinter::newPage whenever you want to move on to the next PDF page).
  • Graphics View
    Qt’s Graphics View framework can be a more suitable alternative for creating PDF documents with content that is mainly based on arbitrarily positioned and transformed 2D graphical items rather than continuous flowed rich text.
    To export the content of a graphics scene or view (or a part of it) to PDF, you need to manually initialize a QPainter configured to paint on a PDF-creating QPrinter (as described above), and pass it to QGraphicsScene::render or QGraphicsView::render.

Using third-party libraries

If you need more control over the output when creating PDF documents, or you need to parse existing PDF documents (anything from extracting specific information to assembling a full in-memory document object tree) and maybe even modify their structure or content before writing them back to disk, refer to third-party PDF reading/writing libraries:

API parsing modifying creating platforms license

poppler-qt4 [freedesktop.org]

C++/Qt yes ? ? Win, Mac?, Linux, … GPL v2+ [strong copyleft]

Hummus [pdfhummus.com]

C++ yes yes yes Win, Mac, Linux Apache 2.0 [permissive]

PoDoFo [podofo.sourceforge.net]

C++ yes yes yes Win, Mac, Linux LGPL [weak copyleft]

Using batch conversion tools

If all else fails, there is always the option of using an existing tool to automatically convert between PDF files and a more manageable format, and let your Qt application read/write that format instead. The conversion tool could be bundled with your application or specified as a prerequisite, and controlled via QProcess. Some possibilities are:

executable names .pdf to: … to .pdf platforms license

poppler-utils [freedesktop.org]

pdftotext, pdftocairo, pdftohtml .txt .svg .html … Win, Mac?, Linux, … GPL v2+ [strong copyleft]

Inkscape [inkscape.org]

inkscape .svg … .svg … Win, Mac, Linux, … GPL v2 [strong copyleft]

Rendering

Using third-party libraries/tools

For rendering pages or elements from existing PDF documents to image files or in-memory pixmaps (useful e.g. for thumbnail generation or implementing custom viewers), third-party libraries can be used:

API can render output to platforms license

poppler-qt4 [freedesktop.org]

C++/Qt pages, …? QImage Win, Mac?, Linux, … GPL v2+ [strong copyleft]

muPDF [mupdf.com]

C pages RGBA byte array Win, Mac, Linux, … GPL v3+ [strong copyleft]; or commercial

Alternatively, the task can be delegated to existing command-line tools:

executable names can render output to platforms license

poppler-utils [freedesktop.org]

pdftocairo, pdftoppm, pdfimages pages, image elements .png .jpg .svg .ppm … Win, Mac?, Linux, … GPL v2+ [strong copyleft]

muPDF [mupdf.com]

pdfdraw pages .png, .ppm, .pgm, .pam, .pbm Win, Mac, Linux, … GPL v3+ [strong copyleft]; or commercial

Interactive Viewing

Calling an external viewer application

If your application merely needs to let the user view/read certain PDF documents on demand, displaying them within the UI of the application itself might not be necessary, and delegating the task to an existing viewer application can be a viable option.

Many users have already chosen and installed a stand-alone PDF viewer according to their personal preferences, so simply letting the operating system open the PDF file with whatever it considers the default viewer for such files, might be the easiest (and potentially most user-friendly) choice.
To do so, simply pass the PDF file’s URL to QDesktopServices::openUrl. If you’re downloading the file from the Internet, store it on disk using QTemporaryFile first, since not all viewers can handle remote URLs.

Using a third-party Qt widget

The following widgets provide native PDF viewing for Qt applications:

class name platforms license

XpdfWidget/Qt [glyphandcog.com]

XpdfWidget Win, Mac, Linux, … commercial

Embedding a third-party ActiveX control

If you are exclusively targeting the Windows platform, you can embed an existing ActiveX component for viewing PDFs in your Qt applications by instantiating it as a QAxWidget (see Qt’s ActiveX Framework).

The following PDF viewers provide such an ActiveX control:

DLL file ActiveX control name platforms license

Adobe Reader [get.adobe.com]

Acropdf.dll AxAcroPDFLib.AxAcroPDF Win, Mac, Linux, … freeware (for commercial redistribution see here [adobe.com])

In the case of the Adobe Reader control, opening a PDF file is done with:

Embedding a third-party browser plugin

A more cross-platform technology for embedding reusable components is the NPAPI [en.wikipedia.org] browser plugin architecture – which Qt’s WebKit-based browser framework happens to support. You’ll need to set up a simple HTML page containing appropriate <embed>…</embed> tags, and let a QWebView display it (with QWebSettings::PluginsEnabled set to true).

The following applications provide a reusable NPAPI plugin for viewing PDF:

1 While in theory it should work on all Desktop platforms, application developers have reported problems in trying to get it to work with Qt Webkit on Linux.

As an alternative to using QWebView for running the plugin, it is possible to use a third-party solution that allows embedding NPAPI plugins in a Qt application without the overhead of a full web browser instance:

component type has special convenience API for platforms license

QtitanMultimedia [devmachines.com]

QWidget Adobe Reader, … Win, Linux commercial

Implementing a custom viewer

TODO: Tips for implementing a custom interactive viewer, using Qt and the PDF parsing and rendering libraries mentioned above

.

See Also

Categories: