Convert component to image/Base64 (v8)

I’m aware that it’s possible to add an image/Base64 into the UI as shown [here]
(https://vaadin.com/forum/thread/1718469), however I’m wondering if it’s possible to convert components in other views to a byte array or Base64 string? I’m writing in pure Java and not using any HTML/JS.

Let’s say I have 2 views within my Navigator, A and B.

  • View A has some Vertical Layouts that I wish to convert to an image, byte array or Base64 string.
  • View B has a Button that creates a PDF containing those Vertical Layouts whenever the user clicks it.

I’m aware of [this add-on]
(https://vaadin.com/directory/component/html2canvas-screenshot) which takes a screenshot of the UI and creates a byte array for the user, but it requires the components to be physically visible, which isn’t possible if the layouts are in a different view.

I don’t want to quickly switch from View A to View B, nor quickly flash the component on the screen as this is hacky and not reliable.

I could use [Apache PDFBox]
(https://pdfbox.apache.org/) to build the components directly into the PDF but it’s very tedious and much easier to build with Vaadin and then simply insert the images into the PDF using PDFBox.

Any suggestions? Thank you kindly.

I’m aware of this add-on which takes a screenshot of the UI and creates a byte array for the user, but it requires the components to be physically visible, which isn’t possible if the layouts are in a different view.

This is probably the only way. The page really needs to be get rendered first, so that all styles (CSS) etc. are applied.

Technically speaking, that could be done in server by running the page via PhantomJS or headless Chrome. That is how it is done with TestBench, when taking screen shots

https://vaadin.com/docs/v8/testbench/creatingtests/testbench-screenshots.html

So, yes there is no simple way to do this.

What is the problem you are trying to solve with this? What is the goal? There could be another path …

@Tatu, thanks for the reply.

My ultimate goal is to have one of my views be responsible for producing an “overview report” in PDF form, once the user clicks a button.

The overview report essentially will produce a PDF that contains many of the components that are visible in multiple other views (not just one other) throughout the Vaadin application.

For example:

  • One view is responsible for producing charts using the [ChartJS add-on]
    (https://vaadin.com/directory/component/chartjs-add-on).

  • One view is responsible for building styled Vertical Layouts using many custom CSS styling. These boxes could likely be reproduced in PDFBox but would be tedious and would also be doubling my work, as opposed to just using the already constructed Vertical Layouts from the UI.

Some other views produce other components which also need to be added to the overview PDF.

I’m basically trying to not double my workload by using PDFBox to build visuals that are already constructed in the UI. Perhaps PhantomJS is my best option? I don’t see any mention of PhantomJS in the testbench link you provided. Ideally, the solution should work on all screen resolutions including mobile.

Thanks for any other feedback.

@Tatu, any suggestions based on my explanation?

Thank you.

I understand that your case is like printing solution. In that case TestBench example is not a good one, since it uses utilities that are not applicable in your case.

But, otherwise yes. Rendering page to a PDF file via headless browser such as PhantomJS and then downloading the resulting file is the way to go. You probably want to have URI parameter in your view, which indicates, it has been called in “printing mode”, so that you can apply different layout and style names in case those are needed for optimal result (e.g. also possible need for paging).

Charts usually needs special attention (see https://vaadin.com/docs/v8/charts/java-api/charts-advanced.html and the add-on you have found is probably tackling same)

Creating PDF export actually contains lot of special cases, which can be hard to solve and specific to application. Thus it is not just like walk in the park.

I understand what you’re saying I might opt to build manually in PDFBox as it seems like it might be an equal amount of work, and more solid.

Thanks for your time.