cefpython
cefpython copied to clipboard
PDF printing support
Printing to PDF can be performed in two ways:
-
When print dialog appears you should see "Print to PDF" option (printer). This is already available.
-
There is a new method CefBrowserHost::PrintToPDF(), but this wasn't yet exposed in CEF Python.
See these commits by cuijinbao for reference: https://github.com/cztomczak/cefpython/commit/aec34742a71662dae21cfa3b2102fba28b1952f4 and https://github.com/cztomczak/cefpython/commit/7dc6d7d9d8b2a9c2662a196c5ccb3b1a135867f7 .
Below is the code from CEF header files that would need to be exposed:
PrintToPDF function
///
// Print the current browser contents to the PDF file specified by |path| and
// execute |callback| on completion. The caller is responsible for deleting
// |path| when done. For PDF printing to work on Linux you must implement the
// CefPrintHandler::GetPdfPaperSize method.
///
/*--cef(optional_param=callback)--*/
virtual void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) =0;
Print settings
///
// Structure representing PDF print settings.
///
typedef struct _cef_pdf_print_settings_t {
///
// Page title to display in the header. Only used if |header_footer_enabled|
// is set to true (1).
///
cef_string_t header_footer_title;
///
// URL to display in the footer. Only used if |header_footer_enabled| is set
// to true (1).
///
cef_string_t header_footer_url;
///
// Output page size in microns. If either of these values is less than or
// equal to zero then the default paper size (A4) will be used.
///
int page_width;
int page_height;
///
// The percentage to scale the PDF by before printing (e.g. 50 is 50%).
// If this value is less than or equal to zero the default value of 100
// will be used.
///
int scale_factor;
///
// Margins in millimeters. Only used if |margin_type| is set to
// PDF_PRINT_MARGIN_CUSTOM.
///
double margin_top;
double margin_right;
double margin_bottom;
double margin_left;
///
// Margin type.
///
cef_pdf_print_margin_type_t margin_type;
///
// Set to true (1) to print headers and footers or false (0) to not print
// headers and footers.
///
int header_footer_enabled;
///
// Set to true (1) to print the selection only or false (0) to print all.
///
int selection_only;
///
// Set to true (1) for landscape mode or false (0) for portrait mode.
///
int landscape;
///
// Set to true (1) to print background graphics or false (0) to not print
// background graphics.
///
int backgrounds_enabled;
} cef_pdf_print_settings_t;
Print callback
///
// Callback interface for CefBrowserHost::PrintToPDF. The methods of this class
// will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefPdfPrintCallback : public virtual CefBaseRefCounted {
public:
///
// Method that will be executed when the PDF printing has completed. |path|
// is the output path. |ok| will be true if the printing completed
// successfully or false otherwise.
///
/*--cef()--*/
virtual void OnPdfPrintFinished(const CefString& path, bool ok) =0;
};
I'm interested in this. I'm using both chromium (custom hacked with a couple of weird features) and cefpython but still using phantomjs for rendering docs as PDF.
How hard is it to implement something like this? I've had a look through cefpython previously and it seems that much of the work is in mapping all the datatypes and function calls between cefpython and cef (though I'm not very familiar with pyx) - is that correct?
@aidos It's a matter of exposing the API above, so it's pretty easy:
- PrintToPDF - add wrapper method in browser.pyx and signatures in cef_browser.pxd
- Print settings - add wrapper in settings.pyx and signatures in cef_types.pxd. Preferably settings should be exposed as classes to provide auto completion/checking in IDE's. See Issue #205.
- Print callback - this can be a bit harder as it requires writing some C++ code as well. See for example string_visitor.cpp, string_visitor.h and string_visitor.pyx.
Also when adding new functions you should update API docs - the api/ directory. PR is welcome.
For editing cefpython code I recommend PyCharm - see config in Issue #232.
Ok great! I'll take a look when I get a moment. First I'll get the build running locally and then I can take a stab at adding the functionality.
Ultimately I want to run my custom chromium build via cefpython so this was already on my list (I know there are a couple of patches to cef required to make them play nice).
For adding custom Chromium/CEF patches to CEF Python see patches/patch.py and Build instructions doc > How to patch. It's best to send them upstream.
https://github.com/qq18436558/cefpython Update to cef 3.3325.1756.g6d8faa4 Add CefFileDialogCallback Add CefFastPdfPrintCallback
Test OnFileDialog and OnPdfPrintFinished on Mac and Win10 in wxpython.py
This commit from @qq18436558 be added?
It needs to go through a PR review process. PDF printing and file dialog callback should be sent as separate PRs, unless they depend on each other.
@cztomczak I'm also very interested in this feature. I'd posted a question on SO a while back about this very function and just came across your work here.
Do you have any projection of a timeline for this? I don't see a PR from @qq18436558 with the changes they made - does one need to be opened?
See https://github.com/cztomczak/cefpython/pull/422
How to use it in Python?