2010-05-12 42 views
9

Tôi có trang GWT nơi người dùng nhập dữ liệu (ngày bắt đầu, ngày kết thúc, v.v.), sau đó dữ liệu này sẽ chuyển đến máy chủ qua cuộc gọi RPC. Trên máy chủ tôi muốn tạo báo cáo Excel với POI và cho phép người dùng lưu tệp đó trên máy cục bộ của họ.Tải xuống tệp động với GWT

Đây là mã thử nghiệm của tôi để truyền tập tin lại cho khách hàng nhưng đối với một số lý do tôi nghĩ rằng nó không biết làm thế nào để dòng tập tin cho khách hàng khi tôi đang sử dụng 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; 
    } 
} 

Tôi đã đọc một nơi nào đó trên internet mà bạn không thể làm dòng tập tin với RPC và tôi phải sử dụng Servlet cho điều đó. Có ví dụ nào về cách sử dụng Servlet và cách gọi servlet đó từ ReportsServiceImpl. Tôi có thực sự cần phải thực hiện một servlet hoặc nó có thể dòng nó trở lại với RPC của tôi?

+0

Xin hãy giải thích vấn đề một cách chi tiết hơn. "nó không biết" là không thực sự mô tả. Chính xác thì điều gì xảy ra? Điều gì xảy ra chính xác không? – BalusC

+1

Câu trả lời của @sri có ý nghĩa. Bây giờ đến lượt của tôi để đăng một số ý kiến: 1) 'DataInputStream' là superflous. Chỉ cần sử dụng thẳng 'FileInputStream'. Bạn sau khi tất cả * chỉ * cần phương thức 'read()' được xác định trong lớp 'InputStream'. 2) Kiểm tra 'in! = Null' cũng rất đáng kể vì đó là ** không bao giờ ** null (bạn đã tạo mới bằng cách sử dụng' new', không bao giờ có thể rỗng). 3) Đầu đề 'Content-Disposition' trông không đúng định dạng trong phần' filename'. Để có được một số ý tưởng về cách thực hiện tệp * basic *, bạn có thể thấy [this article] (http://balusc.blogspot.com/2007/07/fileservlet.html) hữu ích. Chúc may mắn. – BalusC

Trả lời

14

Bạn phải tạo một Servlet thông thường, bạn không thể dữ liệu nhị phân luồng từ ReportsServiceImpl. Ngoài ra, không có cách nào để gọi servlet từ ReportsServiceImpl - mã máy khách của bạn phải trực tiếp gọi servlet.

Ở phía máy khách, bạn phải tạo một liên kết neo bình thường với các tham số được truyền qua chuỗi truy vấn. Một cái gì đó như <a href="http://myserver.com/myservlet?parm1=value1&.."</a>.

Ở phía máy chủ, hãy di chuyển mã của bạn sang một Servlet tiêu chuẩn, một mã không kế thừa từ RemoteServiceServlet. Đọc các tham số từ đối tượng yêu cầu, tạo excel và gửi lại cho máy khách. Trình duyệt sẽ tự động bật lên hộp thoại tải xuống tệp.

+1

Vâng, điều này có ý nghĩa. Cảm ơn bạn đã đề xuất! – Maksim

0

Có thể lấy dữ liệu nhị phân bạn muốn quay lại kênh RPC theo một số cách ... uuencode, ví dụ. Tuy nhiên, bạn vẫn phải làm cho trình duyệt xử lý tệp dưới dạng tải xuống. Và, dựa trên mã của bạn, có vẻ như bạn đang cố gắng kích hoạt cơ chế trình duyệt chuẩn để xử lý loại mime nhất định bằng cách sửa đổi phản hồi trong máy chủ để trình duyệt sẽ nhận ra nó là một tải xuống ... mở ví dụ như hộp thoại lưu. Để làm điều đó, bạn cần phải có trình duyệt để thực hiện yêu cầu cho bạn và bạn cần servlet ở đó để xử lý yêu cầu. Nó có thể được thực hiện với các url còn lại, nhưng cuối cùng bạn sẽ cần một serviet để làm điều đó.

Bạn cần, có hiệu lực, để đặt URL cửa sổ trình duyệt thành URL gửi lại đối tượng phản hồi đã sửa đổi.

Vì vậy, câu hỏi này (về luồng) không thực sự tương thích với mẫu mã. Một hoặc khác (giao thức truyền thông hoặc đối tượng phản ứng sửa đổi máy chủ) phải được điều chỉnh.

Cách dễ nhất để điều chỉnh là phương pháp giao tiếp.

+0

oh xin lỗi chỉ cần đọc ngày – Rondo

2

Bạn có thể làm điều đó chỉ sử dụng GWT RPC và Data URIs:

  1. Trong ví dụ của bạn, hãy myMethod trả hồ sơ nội dung của bạn.
  2. Ở phía máy khách, định dạng Data URI với nội dung tệp đã nhận.
  3. Sử dụng Window.open để mở hộp thoại lưu tệp qua định dạng DataURI.

Hãy nhìn vào thông tin này, để hiểu việc sử dụng Data URI:

Export to csv in jQuery

+1

Cần phải xem xét rằng DATA URI không được hỗ trợ trên IE 6 & 7. IE8 có hỗ trợ một phần mặc dù. – codingscientist