chromiumembedded / cef

Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.
https://bitbucket.org/chromiumembedded/cef/
Other
3.1k stars 451 forks source link

Windows: PrintToPdf on website which displays a PDF opens windows print dialog. #2790

Open magreenblatt opened 4 years ago

magreenblatt commented 4 years ago

Original report by Mark Leutloff (Bitbucket: Mark Leutloff).


Version: Cef3

Chromium: 78.0.3904.34

OS: Windows 10 x86/x64

What I expect to see:

PrintToPDF will print the content of the website to the specified pdf filepath.

What I can see:

PrintToPDF will NOT create the specified pdf, but instead opens the windows print dialog which allows me to select the printer I want to use to print the PDF which is beeing displayed in the website.

How to reproduce:

Load a website which serves a pdf (for example: http://www.orimi.com/pdf-test.pdf) and then call:

browser->GetHost()->PrintToPDF(…);

magreenblatt commented 4 years ago

This also reproduces with CEF v77.

magreenblatt commented 4 years ago

Original comment by Remco Volwater (Bitbucket: Remco Volwater).


This also (still) occurs in

v79.1.36
v81.2.17

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


I wanted to update from old v71 to current version … but this issue finally stopped my plan.
The issue still exists in CEF 84.4.1
Please fix it.

magreenblatt commented 3 years ago

Original comment by Alex Maitland (Bitbucket: a-maitland).


Try using DevTools as a workaround https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF

CEF now supports issuing DevTools commands directly see #2961/add-support-for-direct-communication-over

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


Thank you for the suggested workaround.
I managed to call the devtools but unfortunately it does not work.

I call execute_dev_tools_method with "Page.printToPDF". In on_dev_tools_method_result i get this result back:
{"code":-32000,"message":"PrintToPDF is not implemented"}

This issue prevents me from updating, i hope it gets solved soon.

magreenblatt commented 3 years ago

Original comment by cmsmor (Bitbucket: cmsmor, GitHub: cmsmor).


I’m interested in this feature too.

Thanks

magreenblatt commented 3 years ago

Original comment by Salvador Diaz Fau (Bitbucket: salvadordf, GitHub: salvadordf).


I tested this issue with the latest cefclient (85.3.11) on Windows 10 64 bits and I get a PDF file with a header and a footer but the content is missing.
http://opensource.spotify.com/cefbuilds/cef_binary_85.3.11%2Bg3644604%2Bchromium-85.0.4183.102_windows64_client.tar.bz2

Steps to reproduce this issue :

I also tried the "Page.printToPDF" method in CEF4Delphi and I get the same error code (-32000) and message : “PrintToPDF is not implemented"

magreenblatt commented 3 years ago

Original comment by Alex Maitland (Bitbucket: a-maitland).


Further investigation and Chrome only supports Page.printToPDF when in headless mode.

https://github.com/puppeteer/puppeteer/issues/830

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


Thank you Alex Maitland.
This means, your suggested workaround can work only in offscreen mode apps, it does not affect the possibility to fix the issue in CEF, right?

magreenblatt commented 3 years ago

Original comment by Alex Maitland (Bitbucket: a-maitland).


Page.printToPDF is not usable in CEF. You can manually download the PDF checking the url/mime type to determine if a PDF is displayed.

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


ok, thank you!
Yes, i can determine whether a PDF is displayed (i already do this) and probably i can figure out the URL.
I then can download the PDF in many cases. But when it’s no static PDF file which is often the case for my users, when the PDF is generated by a web application which requires login, cookies, valid viewstate etc. it may be not possible or at least very very difficult.
Getting the PDF from the browser cache is not possible when i remember right, i think i have looked for this option in the past.
Another option for a workaround would be to try to capture the PDF bytes while it’s loaded by CEF, save it in temp files and use them instead PrintToPDF. I tried this option a few years ago without success that time, it failed on larger files for some reason i was not able to figure out. Maybe i try it again if i cannot wait to get this issue fixed in CEF.

magreenblatt commented 3 years ago

Original comment by Mark Leutloff (Bitbucket: Mark Leutloff).


I was able to print the pdf, but the behaviour to reach that result was very strange. Best I describe it with the cefclient.exe:

  1. Start cefclient.exe
  2. Menu: Tests->Other tests->PDF Viewer direct
  3. Menu: Tests->PrintToPdf

Result: Not the PDF content is printed, but everything except the PDF is printed (like the PDF Viewer background eg.). This is what Salvador Diaz Fau has described.

But following steps will print the PDF:

  1. Start cefclient.exe
  2. Menu: Tests->Other tests->PDF Viewer direct
  3. Click into the PDF
  4. Menu: Tests->PrintToPdf

Result: The PDF is printed.

Now for even more strange fun:

  1. Start cefclient.exe
  2. Menu: Tests->Other tests->PDF Viewer iframe
  3. Click into a PDF
  4. Menu: Tests->PrintToPdf

Result: Not the PDFs are printed, but everything except the PDFs are printed (like the PDF Viewer background eg.).

The issue is also present with the 4240 branch (with Chromium 86) of Cef

magreenblatt commented 3 years ago

PDF viewer functionality may be removed from the Alloy runtime in the future (see issue #3048), in which case this issue would be closed as WontFix.

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


Thank you for the update!
Sounds like much work.
If you do the proposed changes, what does this mean for displaying and printing PDF.
Are PDF’s still viewable in the CEF browser, in WinForms and OSR?
Is there then still a PrintToPdf function available (WinForms and OSR)?
I guess this are silly questions, but as “end-user” i don’t understand fully what all this means.

magreenblatt commented 3 years ago

The PrintToPDF method will still be available, but you will potentially be unable to display PDF files in CEF. See issue #3048 for related discussion.

magreenblatt commented 3 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


OK. I hope viewing PDF’s will still be possible, in WinForms and OSR. But it seems to be uncertain how this Chromium and CEF changes will be finally.
In any case, thank you for working on this excellent project!

magreenblatt commented 3 years ago

This is still an issue with M90 (4430 branch).

magreenblatt commented 3 years ago

Original comment by Kevin Krüger (Bitbucket: Kevin Krüger).


Hi, i have the same problem.

I come from this issue(for more detials):

https://github.com/cefsharp/CefSharp/issues/3650#issuecomment-869670245

magreenblatt commented 3 years ago

Original comment by Alex Maitland (Bitbucket: a-maitland).


It looks like Chromium is adding support for DevTools printtopdf in headful mode. Changes is still in code review stage

https://chromium-review.googlesource.com/c/chromium/src/+/2764605

magreenblatt commented 3 years ago

Original comment by Kevin Krüger (Bitbucket: Kevin Krüger).


What is the approximate date I can expect?

No offense, but I need the "feature" in a timely manner.

Would be very very cool if you could set it up.

I know I'm one of many who also need something else and I've also seen that Cef is also partly written in C++, which might make the whole thing not so easy to do with a snap of the fingers, honestly! I take my hat off for your achievement in this project!

Greetings Kevin

magreenblatt commented 3 years ago

A PR to fix this issue would be welcome.

magreenblatt commented 2 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


Just wondering if anyone has a workaround for this?
Would really like to update to a recent CEF version now but cannot because of this issue.

magreenblatt commented 2 years ago

This does not reproduce in M99 when using --enable-print-preview. It still reproduces when not using that flag.

magreenblatt commented 2 years ago

The problem is that PrintRenderFrameHelper::PrintNode is calling Print() instead of RequestPrintPreview() when not passing --enable-print-preview (due to g_is_preview_enabled being false). That triggers a call to CefPrintViewManager::GetDefaultPrintSettings and display of the print dialog.

When there isn’t a PDF element PrintRenderFrameHelper::InitiatePrintPreview instead calls RequestPrintPreview() directly, and everything behaves as expected.

Call stack for the unexpected Print() call:

>   libcef.dll!printing::PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) Line 2211    C++
    libcef.dll!printing::PrintRenderFrameHelper::CalculateNumberOfPages(blink::WebLocalFrame * frame, const blink::WebNode & node, unsigned int * number_of_pages) Line 2237    C++
    libcef.dll!printing::PrintRenderFrameHelper::Print(blink::WebLocalFrame * frame, const blink::WebNode & node, printing::PrintRenderFrameHelper::PrintRequestType print_request_type) Line 1940  C++
    libcef.dll!printing::PrintRenderFrameHelper::PrintNode(const blink::WebNode & node) Line 1916   C++
    libcef.dll!printing::PrintRenderFrameHelper::InitiatePrintPreview(mojo::PendingAssociatedRemote<printing::mojom::PrintRenderer> print_renderer, bool has_selection) Line 1366   C++
    libcef.dll!printing::mojom::PrintRenderFrameStubDispatch::Accept(printing::mojom::PrintRenderFrame * impl, mojo::Message * message) Line 2856   C++
    libcef.dll!printing::mojom::PrintRenderFrameStub<mojo::RawPtrImplRefTraits<printing::mojom::PrintRenderFrame>>::Accept(mojo::Message * message) Line 584    C++

magreenblatt commented 2 years ago

Use --enable-print-preview in combination with PrintToPDF() of PDF documents.

magreenblatt commented 2 years ago

Original comment by Alex Maitland (Bitbucket: a-maitland).


OSR doesn’t support print preview, so I don’t believe that workaround will work in that context. Perhaps we could add a separate command line argument to enable the native print preview dialog when using OSR?

Open to other suggestions.

magreenblatt commented 2 years ago

Using PrintToPDF on a document that is already a PDF file is a bit of an odd use case to begin with, when you can just directly download the PDF file instead.

It might be reasonable to support a headless print-preview mode just for OSR + PrintToPDF, but that would depend on the complexity involved.

magreenblatt commented 2 years ago

Original comment by Andy Buergel (Bitbucket: Andy9876, GitHub: Andy9876).


It is not always possible to just directly download the PDF file.
When the PDF is no static PDF file, when the PDF is generated by a web application which requires login, cookies, perform certain steps on the website, valid viewstate etc. it may be not possible or at least very difficult to download the PDF.

magreenblatt commented 2 years ago

Looks like something more is required for OSR.

magreenblatt commented 4 years ago
magreenblatt commented 2 years ago
magreenblatt commented 2 years ago