2010-05-12 60 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