Search This Blog

Loading...

Friday, September 3, 2010

Printing in Vaadin

In one of my recent projects for one of our clients, I have used the Vaadin framework to develop the application. One of the requirements of this application was to print certain content. I basically evaluated three possible solutions to implement this functionality:

  1. Create a new window with content specifically designed for printing and use the JavaScript print() method to print the contents of this window;
  2. Create a PDF with the printable contents and open this PDF in a new browser window;
  3. Create a PDF with the printable contents and use the Embedded and Window components to display the PDF.

I found option 1 not compatible and consistent enough between browsers. To create a consistent look&feel of the printable contents I used PDF. One way to display this PDF to the end-user is to open a new browser window. Unfortunately this was hindered by popup blockers which is not acceptable to end-users of the application.

Option 3 involved using an Embedded component to display the PDF inside a native Vaadin popup window (which is a regular div). This way, the printable contents are always consistent (because PDF is used) and the popup with the PDF contents is not hindered by browser popup blockers because the popup is just a regular div. By using this method, the print window also integrated nicely with the visual appearance of the rest of the application. The following code demonstrates how to implement this functionality:
/**
* This class creates a PDF with the iText library. This class implements
* the StreamSource interface which defines the getStream method.
*/
public class Pdf implements StreamSource {
private final ByteArrayOutputStream os = new ByteArrayOutputStream();

public Pdf() {
Document document = null;

try {
document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter.getInstance(document, os);
document.open();

document.add(new Paragraph("This is some content for the sample PDF!"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document != null) {
document.close();
}
}
}

@Override
public InputStream getStream() {
// Here we return the pdf contents as a byte-array
return new ByteArrayInputStream(os.toByteArray());
}
}


And the code for displaying a popup with the actual PDF viewer:
Window window = new Window();
((VerticalLayout) window.getContent()).setSizeFull();
window.setResizable(true);
window.setWidth("800");
window.setHeight("600");
window.center();
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);

// Here we create a new StreamResource which downloads our StreamSource,
// which is our pdf.
StreamResource resource = new StreamResource(new Pdf(), "test.pdf?" + System.currentTimeMillis(), this);
// Set the right mime type
resource.setMIMEType("application/pdf");

e.setSource(resource);
window.addComponent(e);
getMainWindow().addWindow(window);


A full, working example including PDF generation, can be found here. The example project demonstrates displaying the PDF with and without a popup.

What is your experience with printable content in a Vaadin application?
Post a Comment