How to start a file download in vaadin without button?

后端 未结 2 1870
我在风中等你
我在风中等你 2021-02-04 09:21

I know that it is really easy to create a FileDownloader and call extend with a Button. But how do I start a download without the Button?

相关标签:
2条回答
  • 2021-02-04 09:58

    I found a solution myself. Actually two. The first one uses the deprecated method Page.open()

    public class DownloadComponent extends CustomComponent implements ValueChangeListener {
    private ComboBox cb = new ComboBox();
    
    public DownloadComponent() {
        cb.addValueChangeListener(this);
        cb.setNewItemsAllowed(true);
        cb.setImmediate(true);
        cb.setNullSelectionAllowed(false);
        setCompositionRoot(cb);
    }
    
    @Override
    public void valueChange(ValueChangeEvent event) {
        String val = (String) event.getProperty().getValue();
        FileResource res = new FileResource(new File(val));
        Page.getCurrent().open(res, null, false);
    }
    }
    

    The javadoc here mentions some memory and security problems as reason for marking it deprecated


    In the second I try to go around this deprecated method by registering the resource in the DownloadComponent. I'd be glad if a vaadin expert comments this solution.

    public class DownloadComponent extends CustomComponent implements ValueChangeListener {
    private ComboBox cb = new ComboBox();
    private static final String MYKEY = "download";
    
    public DownloadComponent() {
        cb.addValueChangeListener(this);
        cb.setNewItemsAllowed(true);
        cb.setImmediate(true);
        cb.setNullSelectionAllowed(false);
        setCompositionRoot(cb);
    }
    
    @Override
    public void valueChange(ValueChangeEvent event) {
        String val = (String) event.getProperty().getValue();
        FileResource res = new FileResource(new File(val));
        setResource(MYKEY, res);
        ResourceReference rr = ResourceReference.create(res, this, MYKEY);
        Page.getCurrent().open(rr.getURL(), null);
    }
    }
    

    Note: I do not really allow the user to open all my files on the server and you should not do that either. It is just for demonstration.

    0 讨论(0)
  • 2021-02-04 09:58

    Here is my work-around. It works like a charm for me. Hope it will help you.

    1. Create a button and hide it by Css (NOT by code: button.setInvisible(false))

      final Button downloadInvisibleButton = new Button();
      downloadInvisibleButton.setId("DownloadButtonId");
      downloadInvisibleButton.addStyleName("InvisibleButton");
      

      In your theme, add this rule to hide the downloadInvisibleButton:

      .InvisibleButton {
          display: none;
      }
      
    2. When the user clicks on menuItem: extend the fileDownloader to the downloadInvisibleButton, then simulate the click on the downloadInvisibleButton by JavaScript.

      menuBar.addItem("Download", new MenuBar.Command() {
        @Override
        public void menuSelected(MenuBar.MenuItem selectedItem) {
          FileDownloader fileDownloader = new FileDownloader(...);
          fileDownloader.extend(downloadInvisibleButton);
          //Simulate the click on downloadInvisibleButton by JavaScript
          Page.getCurrent().getJavaScript()
             .execute("document.getElementById('DownloadButtonId').click();");
        }
      });
      
    0 讨论(0)
提交回复
热议问题