Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Issue closing modal window after downloading created PDF using URI handler

Christian Andersson
1 decade ago Mar 02, 2010 2:45pm
Jean-François Lamy
1 decade ago Mar 02, 2010 5:09pm

I don't know how you create your PDF. Here is the code I use to allow people to download an Excel, which relies on Vaadin StreamResource to deal with all the ugly mess. Same should work with PDFs or other files.

Note that there is some kludgery to deal with IE, what else could be expected.

StreamResource streamResource = new StreamResource(streamSource, filename+".xls", this);
streamResource.setCacheTime(5000); // no cache (<=0) does not work with IE8
streamResource.setMIMEType("application/x-msexcel");
this.getMainWindow().open(streamResource,"_top");

In the above code, streamSource contains the bytes. I suspect your package creates a OutputStream, but StreamResource wants an InputStream. In order to convert, you can use

PipedInputStream in = new PipedInputStream();
			final PipedOutputStream out = new PipedOutputStream(in);

You write on "out", and you create your Vaadin StreamResource with "in"

Risto Yrjänä
1 decade ago Mar 03, 2010 9:40am
Christian Andersson
1 decade ago Mar 04, 2010 5:59pm

Thank you for your quick reply. It really helped out a lot. :)
I did not use the piped stream advice since I am not using inter-thread communication but rather one single execution thread.
I thought I would post my final solution here, it might help someone else out there.

Do note that I did not want the browser to open the pdf file using a browser plugin but rather ask whether to download the file or open the file. Thus, I use the MIME type "binary-octet" and set the "attachment" value for "content-disposition" (a fix for IE).
If you would like the pdf file to open inside the browser (and most likely replace your Vaadin application) you should change the MIME type to appropriate value and comment out the line with setting of "content-disposition" parameter to "attachment". To open the pdf in the another browser window (or browser tab) than your Vaadin application you can probably also change the "_top" value to either "_blank" or any other unique name for the new window.

The code open download binary data that have been dynamically created (i.e. not a file stored somewhere on disc).

public void downloadReport(final ReportParameters reportParameters, final Component component) {
  final byte[] pdfData = createPdfReport(reportParameters);
	
  final String pdfFileName = getPdfFileName(reportParameters);

  // Set MIME type to binary data to prevent opening of pdf in browser window
  final DynamicStreamResource streamResource = 
    new DynamicStreamResource(pdfData, pdfFileName, 
      [color=#5F0000][b]DynamicStreamResource.MIME_TYPE_BINARY_DATA[/b][/color], component.getApplication());

  streamResource.setCacheTime(5 * 1000); // no cache (<=0) does not work with IE8, (in milliseconds)
  component.getApplication().getMainWindow().open(streamResource, "[color=#5F0000][b]_top[/b][/color]");
}

I have hidden some implementation in the class DynamicStreamResource.

package com.acme.download;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import com.vaadin.Application;
import com.vaadin.terminal.DownloadStream;
import com.vaadin.terminal.StreamResource;

public class DynamicStreamResource extends StreamResource {

  private static final long serialVersionUID = -4304057799149311779L;
  
  public static final String MIME_TYPE_BINARY_DATA = "application/octet-stream";
  public static final String MIME_TYPE_PDF = "application/pdf";

  private final byte[] binaryData;

  private final String filename;

  public DynamicStreamResource(final byte[] binaryData, final String filename, 
        final String mimeType, final Application application) {
    super(new StreamSource() {

      @Override
      public InputStream getStream() {
        return new ByteArrayInputStream(binaryData);
      }
    }, filename, application);
    
    this.binaryData = binaryData;
    this.filename = filename;
    
    setMIMEType(mimeType);
  }
  
  @Override
  public DownloadStream getStream() {
    final DownloadStream downloadStream = super.getStream();

    // Set the "attachment" to force save-dialog. Important for IE7 (and probably IE8)
    [color=#5F0000][b]downloadStream.setParameter("Content-Disposition", "attachment; filename=\"" + filename + "\"");[/b][/color]

    // Enable deterministic progressbar for download
    [color=#5F0000][b]downloadStream.setParameter("Content-Length", Integer.toString(binaryData.length));[/b][/color]
    
    return downloadStream;
  }

}
Jean-François Lamy
1 decade ago Mar 04, 2010 10:15pm
Benicio Sanchez
1 decade ago Oct 11, 2010 7:15pm
Benicio Sanchez
1 decade ago Oct 11, 2010 10:18pm
Long Ma
1 decade ago Oct 14, 2010 3:04am
David Whiteman
1 decade ago Sep 08, 2011 6:40pm
Marko Grönroos
1 decade ago Sep 08, 2011 6:59pm
David Whiteman
1 decade ago Sep 12, 2011 2:33pm
张 美玲
6 years ago Jun 03, 2015 8:53am
Ranjan Singh
5 years ago Dec 13, 2016 1:25pm