Java Vaadin - 下载文件/另存为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21937516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:30:17  来源:igfitidea点击:

Vaadin - download the file / save as

javadownloadvaadin7

提问by PDS

I try to add button with function to download the file from external resource

我尝试添加具有从外部资源下载文件的功能的按钮

Button saveAsButton = new Button();
private FileDownloader fileDownloader;
fileDownloader = new FileDownloader(new ExternalResource(........));
fileDownloader.extend(saveAsButton);

This doesn't work for me :/ no errors in the background

这对我不起作用:/后台没有错误

回答by nexus

Use a FileResource instead of ExternalResource. In order to offer a file for download, the following has been proven:

使用 FileResource 而不是 ExternalResource。为了提供可供下载的文件,已证明以下内容:

Button btn = new Button("Download");
layout.addComponent(btn);

Resource res = new FileResource(new File("/tmp/file.pdf"));
FileDownloader fd = new FileDownloader(res);
fd.extend(btn);

回答by Visruth

Referred from this link. A custom file downloader can give you this functionality. Here is the custom class and demo. The main advantage of using this AdvancedFileDownloaderover inbuilt com.vaadin.server.FileDownloaderis that you can change file path on each button click. In FileDownloader, once a file is set, it cannot be changed i.e. a button can download only the same file on each click.

来自此链接。自定义文件下载器可以为您提供此功能。这是自定义类和演示。使用它而AdvancedFileDownloader不是内置的主要优点com.vaadin.server.FileDownloader是您可以在每次单击按钮时更改文件路径。在 中FileDownloader,一旦设置了文件,就无法更改,即每次单击一个按钮只能下载相同的文件。

AdvancedFileDownloader.java:-

AdvancedFileDownloader.java:-

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

import com.vaadin.server.ConnectorResource;
import com.vaadin.server.DownloadStream;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.Resource;
import com.vaadin.server.StreamResource;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinSession;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinResponse;
import com.vaadin.ui.AbstractComponent;

/**
 * an advanced file downloader
 *
 * @author visruth
 *
 */
public class AdvancedFileDownloader extends FileDownloader {

    /**
     *
     */
    private static final long serialVersionUID = 7914516170514586601L;
    private static final boolean DEBUG_MODE = true;

    private static final Logger logger = java.util.logging.Logger
            .getLogger(AdvancedFileDownloader.class.getName());

    private AbstractComponent extendedComponet;

    private AdvancedDownloaderListener dynamicDownloaderListener;
    private DownloaderEvent downloadEvent;

    public abstract class DownloaderEvent {

        /**
         *
         * @return
         */
        public abstract AbstractComponent getExtendedComponet();

        public abstract void setExtendedComponet(
                AbstractComponent extendedComponet);

    }

    public interface AdvancedDownloaderListener {
        /**
         * This method will be invoked just before the download starts. Thus, a
         * new file path can be set.
         *
         * @param downloadEvent
         */
        public void beforeDownload(DownloaderEvent downloadEvent);
    }

    public void fireEvent() {
        if (DEBUG_MODE) {
            logger.info("inside fireEvent");
        }
        if (this.dynamicDownloaderListener != null
                && this.downloadEvent != null) {
            if (DEBUG_MODE) {
                logger.info("beforeDownload is going to be invoked");
            }
            this.dynamicDownloaderListener.beforeDownload(this.downloadEvent);
        }
    }

    public void addAdvancedDownloaderListener(
            AdvancedDownloaderListener listener) {
        if (listener != null) {
            DownloaderEvent downloadEvent = new DownloaderEvent() {

                private AbstractComponent extendedComponet;

                @Override
                public void setExtendedComponet(
                        AbstractComponent extendedComponet) {
                    this.extendedComponet = extendedComponet;
                }

                @Override
                public AbstractComponent getExtendedComponet() {
                    // TODO Auto-generated method stub
                    return this.extendedComponet;
                }
            };
            downloadEvent
                    .setExtendedComponet(AdvancedFileDownloader.this.extendedComponet);
            this.dynamicDownloaderListener = listener;
            this.downloadEvent = downloadEvent;

        }
    }

    private static class FileResourceUtil {

        private String filePath;

        private String fileName = "";

        private File file;

        public String getFilePath() {
            return filePath;
        }

        public void setFilePath(String filePath) {
            this.filePath = filePath;
            file = new File(filePath);

            if (file.exists() && !file.isDirectory()) {
                fileName = file.getName();
            }
        }

        /**
         * makes a stream resource
         *
         * @return {@code StreamResource}
         */
        @SuppressWarnings("serial")
        public StreamResource getResource() {
            return new StreamResource(new StreamSource() {

                @Override
                public InputStream getStream() {

                    if (filePath != null && file != null) {

                        if (file.exists() && !file.isDirectory()) {
                            try {
                                return new FileInputStream(file);
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                                return null;
                            }
                        } else {
                            return null;
                        }

                    }
                    return null;
                }

            }, FileResourceUtil.this.fileName) {
                @Override
                public String getFilename() {
                    return FileResourceUtil.this.fileName;
                }

            };
        }

    }

    private FileResourceUtil resource;

    private AdvancedFileDownloader(FileResourceUtil resource) {

        super(resource == null ? (resource = new FileResourceUtil())
                .getResource() : resource.getResource());

        AdvancedFileDownloader.this.resource = resource;
        System.out.println("created a new instance of resource : " + resource);
    }

    public AdvancedFileDownloader() {
        this(null);
    }

    /**
     * @return the current file path
     */
    public String getFilePath() {
        return resource.getFilePath();
    }

    /**
     * sets the path for the file for downloading
     *
     * @param filePath
     *            path of the file, i.e. path + file name with extension
     */
    public void setFilePath(String filePath) {

        if (resource != null && filePath != null) {
            this.resource.setFilePath(filePath);
            ;
        }
    }

    @Override
    public boolean handleConnectorRequest(VaadinRequest request,
            VaadinResponse response, String path) throws IOException {


        if (!path.matches("dl(/.*)?")) {
            // Ignore if it isn't for us
            return false;
        }
        VaadinSession session = getSession();

        session.lock();
        AdvancedFileDownloader.this.fireEvent();

        DownloadStream stream;

        try {
            Resource resource = getFileDownloadResource();
            if (!(resource instanceof ConnectorResource)) {
                return false;
            }
            stream = ((ConnectorResource) resource).getStream();

            if (stream.getParameter("Content-Disposition") == null) {
                // Content-Disposition: attachment generally forces download
                stream.setParameter("Content-Disposition",
                        "attachment; filename=\"" + stream.getFileName() + "\"");
            }

            // Content-Type to block eager browser plug-ins from hiHymaning
            // the file
            if (isOverrideContentType()) {
                stream.setContentType("application/octet-stream;charset=UTF-8");
            }

        } finally {
            session.unlock();
        }
        stream.writeResponse(request, response);
        return true;
    }
}

And the demo codo to run. In this code you have to give the file path for downloading the file.

以及要运行的演示代码。在此代码中,您必须提供下载文件的文件路径。

package com.example.samplevaadin;

import javax.servlet.annotation.WebServlet;

import com.example.samplevaadin.ui.componet.custom.AdvancedFileDownloader;
import com.example.samplevaadin.ui.componet.custom.AdvancedFileDownloader.AdvancedDownloaderListener;
import com.example.samplevaadin.ui.componet.custom.AdvancedFileDownloader.DownloaderEvent;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Link;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
@Theme("samplevaadin")
public class DemoUI extends UI {

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = DemoUI.class)
    public static class Servlet extends VaadinServlet {
    }

    @Override
    protected void init(VaadinRequest request) {

        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);


        final TextField inputFilepathField = new TextField();
        inputFilepathField.setValue("/home/visruthcv/README.txt");
        inputFilepathField.setImmediate(true);
        layout.addComponent(inputFilepathField);

        Button downloadButton = new Button("Download Button");
        // or
        Link downloadLink = new Link();
        downloadLink.setCaption("Download link");

        final AdvancedFileDownloader downloader = new AdvancedFileDownloader();
        downloader
                .addAdvancedDownloaderListener(new AdvancedDownloaderListener() {

                    /**
                     * This method will be invoked just before the download
                     * starts. Thus, a new file path can be set.
                     * 
                     * @param downloadEvent
                     */
                    @Override
                    public void beforeDownload(DownloaderEvent downloadEvent) {

                        String filePath = inputFilepathField.getValue();

                        downloader.setFilePath(filePath);

                        System.out.println("Starting downlad by button "
                                + filePath.substring(filePath.lastIndexOf("/")));
                    }

                });

        downloader.extend(downloadButton);
        layout.addComponent(downloadButton);

        final AdvancedFileDownloader downloaderForLink = new AdvancedFileDownloader();
        downloaderForLink
                .addAdvancedDownloaderListener(new AdvancedDownloaderListener() {

                    /**
                     * This method will be invoked just before the download
                     * starts. Thus, a new file path can be set.
                     * 
                     * @param downloadEvent
                     */
                    @Override
                    public void beforeDownload(DownloaderEvent downloadEvent) {

                        String filePath = inputFilepathField.getValue();

                        downloaderForLink.setFilePath(filePath);
                        System.out.println("Starting download by link "
                                + filePath.substring(filePath.lastIndexOf("/")));

                    }

                });

        downloaderForLink.extend(downloadLink);
        layout.addComponent(downloadLink);

        setContent(layout);
    }

}

The beforeDownloadmethod will be invoked when you click the download button so that the file path can be changed to download a different file.

beforeDownload单击下载按钮时将调用该方法,以便可以更改文件路径以下载不同的文件。

回答by stephan

I have two methods and there are some parameters.

我有两种方法,并且有一些参数。

void buttonClick(){
       File file = generateReportFile();
        if (file != null) {
            sendConvertedFileToUser(file, branchName + "_" + sdf.format(new Date()) + ".xlsx");
        }
 }

private File generateReportFile() {

        File tempFile = null;
        FileOutputStream fileOut = null;

        try {

            tempFile = File.createTempFile("tmp", ".xlsx");
            fileOut = new FileOutputStream(tempFile);
            workbook.write(fileOut);

        } catch (final IOException e) {
            return null;
        } finally {
            if (tempFile != null) {
                tempFile.deleteOnExit();
            }
            try {
                if (fileOut != null) {
                    fileOut.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }

        return tempFile;
    }



 private boolean sendConvertedFileToUser(final File fileToExport, final String exportFileName) {

        UI ui = UI.getCurrent();
        TemporaryFileDownloadResource resource;
        try {
            resource = new TemporaryFileDownloadResource(ui, exportFileName, this.EXCEL_MIME_TYPE, fileToExport);
            ui.getPage().open(resource, null, false);
        } catch (final FileNotFoundException e) {
            return false;
        }

        return true;
    }