2010-05-12 81 views
9

我有一个用户输入数据(开始日期,结束日期等)的GWT页面,然后通过RPC调用将此数据发送到服务器。在服务器上,我想用POI生成Excel报告,并让用户将该文件保存在本地机器上。使用GWT下载动态文件

这是我的测试代码流文件返回给客户端,但由于某种原因,我认为它不知道如何当我使用RPC流文件到客户端:

public class ReportsServiceImpl extends RemoteServiceServlet implements ReportsService { 
    public String myMethod(String s) { 

     File f = new File("/excelTestFile.xls"); 

     String filename = f.getName(); 

     int length = 0; 

     try { 
      HttpServletResponse resp = getThreadLocalResponse(); 
      ServletOutputStream op = resp.getOutputStream(); 
      ServletContext context = getServletConfig().getServletContext(); 
      resp.setContentType("application/octet-stream"); 
      resp.setContentLength((int) f.length()); 
      resp.setHeader("Content-Disposition", "attachment; filename*=\"utf-8''" + filename + ""); 

      byte[] bbuf = new byte[1024]; 
      DataInputStream in = new DataInputStream(new FileInputStream(f)); 

      while ((in != null) && ((length = in.read(bbuf)) != -1)) { 
       op.write(bbuf, 0, length); 
      } 

      in.close(); 
      op.flush(); 
      op.close(); 

     } 
     catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     return "Server says: " + filename; 
    } 
} 

我已经阅读互联网上的某个地方,你不能用RPC做文件流,我必须为此使用Servlet。是否有任何示例如何使用Servlet以及如何从ReportsServiceImpl调用该servlet。我真的需要制作一个servlet,还是有可能使用我的RPC进行流式处理?

+0

请更详细地阐述这个问题。 “它不知道”不是真正的描述。究竟发生了什么?究竟发生了什么? – BalusC 2010-05-12 20:52:48

+1

@sri的答案很有意义。现在轮到我发表一些评论:1)'DataInputStream'超级。只需使用直接的'FileInputStream'。毕竟你*只需要''InputStream'类中定义的'read()'方法。 2)'in!= null'检查也是superflous,因为这是**永不**空(你使用'new'创建了一个新的,永远不能为空)。 3)'Content-Disposition'头文件在'filename'部分看起来不正确。要想了解如何执行* basic *文件服务,您可能会发现[本文](http://balusc.blogspot.com/2007/07/fileservlet.html)有用。祝你好运。 – BalusC 2010-05-12 22:33:01

回答

14

你必须做一个普通的Servlet,你的不能流二进制数据从ReportsServiceImpl。此外,无法从ReportsServiceImpl调用servlet - 您的客户端代码必须直接调用该servlet。

在客户端,您必须使用通过查询字符串传递的参数创建正常的锚链接。类似于<a href="http://myserver.com/myservlet?parm1=value1&.."</a>

在服务器端,将您的代码移动到一个标准的Servlet,它不会从RemoteServiceServlet继承。从请求对象读取参数,创建excel并将其发送回客户端。浏览器将自动弹出文件下载对话框。

+1

是的,这是有道理的。感谢您的建议! – Maksim 2010-05-13 16:44:14

0

可以通过多种方式获取想要通过RPC通道返回的二进制数据...... uuencode,例如。但是,您仍然必须让浏览器将该文件作为下载来处理。

而且,根据您的代码,您似乎试图通过修改服务器中的响应来触发标准浏览器机制来处理给定的MIME类型,以便浏览器将其识别为下载... open例如保存对话框。为此,您需要让浏览器为您提出请求,并且您需要在那里的servlet来处理请求。这可以通过其他网址来完成,但最终你需要一个服务员才能做到这一点。

实际上,您需要将浏览器窗口URL设置为发送修改后的响应对象的URL。

所以这个问题(关于流式传输)与代码示例并不真正兼容。必须调整其中一个(通信协议或服务器修改的响应对象)方法。

最容易调整的是通信方法。

+0

哦对不起刚刚读取日期 – Rondo 2011-03-23 00:36:31

2

你可以做,只是用GWT RPC和Data URIs

  1. 在你的榜样,让你myMethod返回文件的内容。
  2. 在客户端,使用收到的文件内容格式化Data URI
  3. 使用Window.open打开一个文件保存对话框,通过格式化的DataURI

看看这个参考,了解Data URI用法:

Export to csv in jQuery

+1

需要考虑的是,IE 6和7不支持DATA URI。但IE8有部分支持。 – codingscientist 2013-10-01 10:06:25