2016-04-14 9 views
1

Ich habe derzeit einen Datei-Download-Prozess in meiner Java-Klasse, unten aufgeführt, um alle Daten in einer SQL-Tabelle zu nehmen und in eine CSV-Datei für den Download von Benutzern zu speichern. Wenn ich jedoch die Datei herunterlade, sind alle Daten gut, außer dass sie an zufälligen Punkten abgeschnitten werden (normalerweise um Zeile 20 der Daten, vorausgesetzt, es gibt mindestens über 100 Datenzeilen). Ich möchte fragen, was ist, wenn ich den Cutoff mache? Ist es Session-bezogen oder ist der Code einfach problematisch?Eclipse CSV Download schneidet Daten ab

public String processFileDownload() { 

    DataBaseBean ckear = new DataBaseBean(); 
    ckear.clearContens(); 
    FacesContext fc = FacesContext.getCurrentInstance(); 
    ExternalContext ec = fc.getExternalContext(); 
    Map<String, Object> m = fc.getExternalContext().getSessionMap(); 
    dbase = (DbaseBean) m.get("dbaseBean"); 
    message = (MessageBean) m.get("messageBean"); 
    dataBean = (DataBean) m.get("dataBean"); 
    dbmsUser = (DbmsUserBean) m.get("dbmsUserBean"); 
    FileOutputStream fos = null; 

    String path = fc.getExternalContext().getRealPath("/temp"); 
    String tableName = dbmsUser.getTableName(); 
    String fileNameBase = tableName + ".csv"; 
    java.net.URL check = getClass().getClassLoader().getResource(
      "config.properties"); 
    File check2 = new File(check.getPath()); 
    path = check2.getParent(); 
    String fileName = path + "/" + dbmsUser.getUserName() + "_" 
      + fileNameBase; 

    File f = new File(fileName); 
    try { 
     f.createNewFile(); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    dbase.connect(); 
    dbase.setQueryType("SELECT"); 
    dbase.executeSQL("select * from " + tableName); 
    if (dbase.getResultSet() == null) { 
     FacesContext.getCurrentInstance().addMessage("myForm3:errmess", 
       new FacesMessage("Table doesn't exist!")); 
     return "failed"; 
    } 
    Result result = ResultSupport.toResult(dbase.getResultSet()); 
    downlaodedrows = result.getRowCount(); 
    Object[][] sData = result.getRowsByIndex(); 
    String columnNames[] = result.getColumnNames(); 
    StringBuffer sb = new StringBuffer(); 
    try { 
     fos = new FileOutputStream(fileName); 

     for (int i = 0; i < columnNames.length; i++) { 
      sb.append(columnNames[i].toString() + ","); 
     } 

     sb.append("\n"); 

     fos.write(sb.toString().getBytes()); 

     for (int i = 0; i < sData.length; i++) { 
      sb = new StringBuffer(); 
      for (int j = 0; j < sData[0].length; j++) { 
       sb.append(sData[i][j].toString() + ","); 
      } 

      sb.append("\n"); 
      fos.write(sb.toString().getBytes()); 
     } 

     fos.flush(); 
     fos.close(); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    String mimeType = ec.getMimeType(fileName); 
    FileInputStream in = null; 
    byte b; 

    ec.responseReset(); 
    ec.setResponseContentType(mimeType); 
    ec.setResponseContentLength((int) f.length()); 
    ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" 
      + fileNameBase + "\""); 

    try { 
     in = new FileInputStream(f); 
     OutputStream output = ec.getResponseOutputStream(); 
     while (true) { 
      b = (byte) in.read(); 
      if (b < 0) 
       break; 
      output.write(b); 
     } 
    } catch (NullPointerException e) { 
     fc.responseComplete(); 
     return "SUCCESS"; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     try { 
      in.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    fc.responseComplete(); 
    return "SUCCESS"; 

} 

Antwort

0

Das Problem scheint zu sein, dass man einfach ein Komma zwischen den Werten anhängen und es ist wahrscheinlich einer der Werte, die Sie schreiben sind ein Trennzeichen enthält, Zeilentrenner oder Anführungszeichen, das wird „break“ das CSV-Format, wenn nicht korrekt entkommen.

Es wäre viel einfacher und schneller CSV-Bibliothek dafür zu verwenden. uniVocity-parsers enthält vorgefertigte Routinen, um Ihre Ergebnismenge in korrekt formatierte CSV-Dateien zu speichern. In Ihrem Fall könnten Sie diese Bibliothek auf folgende Weise verwenden:

ResultSet resultSet = dbase.getResultSet(); 

    // Configure the output format as needed before actually dumping the data: 
    CsvWriterSettings writerSettings = new CsvWriterSettings(); //many settings here, check the tutorials & examples. 
    writerSettings.getFormat().setLineSeparator("\n"); 
    writerSettings.setHeaderWritingEnabled(true); // we want the column names to be printed out as well. 

    // Then create a routines object: 
    CsvRoutines routines = new CsvRoutines(writerSettings); 

    // The write() method takes care of everything. The resultSet and any other resources required are closed by the routine. 
    routines.write(resultSet, new File(fileName), "UTF-8"); 

this helps

Haftungsausschluss: Ich bin der Autor dieser Bibliothek. Es ist Open Source und kostenlos (Apache 2.0. Lizenz)

+0

Hey, Danke für die Antwort und Sie sind richtig. Aber wissen Sie, ob es eine Möglichkeit gibt, "UTF-8" ohne das Framework anzuhängen? Ich kann es nicht verwenden, da es sich um ein spezifisches Projekt mit begrenzten Ressourcen handelt. – jni4

+0

Ich bin froh, dass ich helfen konnte. Lassen Sie den "UTF-8" -Teil einfach weg und schreiben Sie stattdessen "routine.write (resultSet, new File (fileName))". Sie können auch einen FileOutputStream oder eine beliebige Instanz von java.io.Writer verwenden. –

Verwandte Themen