我尝试添加带有下载功能的按钮,以从外部资源下载文件。
Button saveAsButton = new Button();
private FileDownloader fileDownloader;
fileDownloader = new FileDownloader(new ExternalResource(........));
fileDownloader.extend(saveAsButton);
这对我没用 :/ 后台没有错误
我尝试添加带有下载功能的按钮,以从外部资源下载文件。
Button saveAsButton = new Button();
private FileDownloader fileDownloader;
fileDownloader = new FileDownloader(new ExternalResource(........));
fileDownloader.extend(saveAsButton);
这对我没用 :/ 后台没有错误
参考这个链接。
一个自定义的文件下载器可以给你这个功能。这里有自定义类和演示。使用AdvancedFileDownloader
比内置的com.vaadin.server.FileDownloader
更具优势,因为你可以在每个按钮点击时更改文件路径。在FileDownloader
中,一旦设置了文件,就无法更改,即每次单击按钮只能下载相同的文件。
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 hijacking
// the file
if (isOverrideContentType()) {
stream.setContentType("application/octet-stream;charset=UTF-8");
}
} finally {
session.unlock();
}
stream.writeResponse(request, response);
return true;
}
}
以下是运行演示代码,您需要提供下载文件的文件路径。
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);
}
}
beforeDownload
方法会在您单击下载按钮时被调用,以便更改文件路径以下载不同的文件。beforeDownload
方法中打印文件内容,验证它是否打印了所有内容。 - Visruth使用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);
我有两个方法,其中有一些参数。
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;
}