2010-05-12 6 views
9

Ich habe eine GWT-Seite, wo Benutzer Daten eingeben (Startdatum, Enddatum, etc.), dann gehen diese Daten an den Server über RPC-Aufruf. Auf dem Server möchte ich einen Excel-Bericht mit POI erstellen und den Benutzer diese Datei auf seinem lokalen Rechner speichern lassen.Download dynamische Datei mit GWT

Dies ist mein Test-Code-Datei zurück an den Client zu streamen, aber aus irgendeinem Grund finde ich es nicht weiß, wie man die Client-Datei zu streamen, wenn ich RPC bin mit:

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; 
    } 
} 

Ich habe lesen Sie irgendwo im Internet, dass Sie Datei-Stream mit RPC nicht machen können, und ich muss Servlet dafür verwenden. Gibt es ein Beispiel für die Verwendung von Servlet und das Aufrufen dieses Servlets von ReportsServiceImpl. Muss ich wirklich ein Servlet erstellen oder es ist möglich, es mit meinem RPC zu streamen?

+0

Bitte erarbeiten das Problem im Detail. "es weiß nicht" ist nicht wirklich beschreibend. Was genau passiert? Was genau passiert nicht? – BalusC

+1

Die Antwort von @sri macht Sinn. Jetzt ist es an mir, einige Kommentare zu posten: 1) 'DataInputStream' ist überflüssig. Verwenden Sie einfach "FileInputStream". Sie brauchen schließlich * nur * die 'read()' Methode, die in der 'InputStream' Klasse definiert ist. 2) Die 'in! = Null'-Prüfung ist auch überflüssig, da das ** never ** null ist (du hast eine neue mit' new' erstellt, die niemals null sein kann). 3) 'Content-Disposition'-Header sieht im' filename'-Teil fehlerhaft aus. Um ein paar Ideen zu bekommen, wie man die Datei * basic * bereitstellt, kann man [diesen Artikel] (http://balusc.blogspot.com/2007/07/fileservlet.html) nützlich finden. Viel Glück. – BalusC

Antwort

14

Sie müssen ein reguläres Servlet machen, Sie können nicht Stream binäre Daten von ReportsServiceImpl. Es gibt auch keine Möglichkeit, das Servlet über ReportsServiceImpl aufzurufen - Ihr Client-Code muss das Servlet direkt aufrufen.

Auf der Clientseite müssen Sie eine normale Ankerverknüpfung mit den über die Abfragezeichenfolge übergebenen Parametern erstellen. So etwas wie <a href="http://myserver.com/myservlet?parm1=value1&.."</a>.

Verschieben Sie den Code serverseitig in ein Standard-Servlet, das NICHT von RemoteServiceServlet erbt. Lesen Sie die Parameter aus dem Anfrageobjekt, erstellen Sie das Excel und senden Sie es an den Client zurück. Der Browser öffnet automatisch das Dateidownload-Dialogfeld.

+1

Ja, das macht Sinn. Danke für Ihren Vorschlag! – Maksim

0

Es ist möglich, die gewünschten binären Daten auf verschiedene Arten über den RPC-Kanal zu erhalten ... uuencode zum Beispiel. Sie müssen den Browser jedoch trotzdem dazu bringen, die Datei als Download zu verarbeiten.

Und basierend auf Ihrem Code scheint es, dass Sie versuchen, den Standard-Browser-Mechanismus für die Behandlung der gegebenen Mime-Typ durch Ändern der Antwort auf dem Server zu lösen, damit der Browser es als Download erkennen ... öffnen ein Speicherdialog zum Beispiel. Um dies zu tun, müssen Sie den Browser dazu bringen, die Anfrage für Sie zu stellen, und Sie benötigen das Servlet, um die Anfrage zu bearbeiten. Es kann mit Ruhe-URLs gemacht werden, aber letztendlich brauchen Sie eine Dienstleistung, um auch das zu tun.

Sie müssen im Endeffekt eine URL des Browserfensters für die URL festlegen, die das geänderte Antwortobjekt zurücksendet.

Also diese Frage (über Streaming) ist nicht wirklich kompatibel mit dem Codebeispiel. Der eine oder andere Ansatz (Kommunikationsprotokolle oder servermodifiziertes Antwortobjekt) muss angepasst werden.

Am einfachsten ist die Kommunikationsmethode.

+0

oh sorry nur das Datum lesen – Rondo

2

Sie können diese nur mit GWT RPC tun und Data URIs:

  1. In Ihrem Beispiel, machen Sie Ihre myMethod den Inhalt der Datei zurück.
  2. Formatieren Sie auf der Clientseite Data URI mit dem empfangenen Dateiinhalt.
  3. Verwenden Sie Window.open, um einen Dateispeicherdialog zu öffnen, der das formatierte DataURI übergibt.

einen Blick auf diesem Bezug nehmen, die Data URI Nutzung zu verstehen:

Export to csv in jQuery

+1

Beachten Sie, dass Daten-URIs nicht auf IE 6 und 7 unterstützt werden. IE8 hat jedoch teilweise Unterstützung. – codingscientist