[JAVA/servlet] csv bestand exporteren naar gewenste locatie

Pagina: 1
Acties:

  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
Hoi allemaal,

Ik moet een functionaliteti implementeren waarbij een gebruiker met 1 klik op de knop een db tabel kan exporteren naar een csv en die kan opslaan in de door hem gewenste locatie (dus zo'n "oplsaan als" venstertje) met de gewenste bestandsnaam.
Nu ben ik zover gevorderd dat ik de csv bestan kan genereren (in een vooraf ingestelde temp directory), maar ik kan niet uitvissen hoe ik die bestand kan opslaan op een locatie waar ik zelf de voorkeur aan geef.
Dit moet dus vanaf de servlet die ik gebruik aangeroepen worden.
Dit is wat ik tot zover heb:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
public class ExportCorrections extends BaseServlet {

     /**
     * Logger for this class
     */
    static final Logger logger = Logger.getLogger(ExportCogNos.class);

    private ApiLanguage language;

    public void init(ServletConfig servletConfig) {
        .....
    }
    
    public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
   ......
    }
    
    // Generate CSV file for export
    private void proces() {
        
        ApiDisplayDateFormatter addf;          
        CSVWriter writer;
        String filename;

        ApiDb db = null;
        
        logger.info("generateExportFile()");
        
        try {

            db = ApiDb.getPoolInstance("promo");
            db.openConnection();
            db.setLanguage(language);

            // savepoint should be set for unlocking purposes
            // savepoint must be set after analyse tables
            db.setAutoCommit(false);
            db.setSavePoint();
            
            // lock all needed tables
            logger.info("proces() - lock table(s) exclusive");

            db.lockTable("maildepot_correction", ApiDb.LOCKMODUS_SHARE);
            logger.info("proces() - lock table(s) exclusive, ok");
            
            // add maildepot_correction to csv file
            writer = getMaildepotCorrectionFile(db);

            filename = writer.getFile().getAbsolutePath();
[b]Hier moet dus de "writer object" (het csv file) verplaatst+hernoemd 
worden naar gebruikers wens[/b]
//          writer.clean(); // Remove the temporary file
            db.commit();

            logger.info("generateExportFile(), OK");
                
        }
        catch (Exception e) {
            
            logger.error("generateExportFile()", e);

            db.rollback();
            
        }
    }

    private CSVWriter getMaildepotCorrectionFile(ApiDb db) throws Exception {

        ApiConfig config = ApiConfig.getInstance();
        
        CSVWriter writer;
        ResultSet rs;

        writer = null;
        rs = null;

        try {

            logger.info("getMaildepotCorrectionFile() - create MaildepotCorrection file");
            
            writer = new CSVWriter(config.getApplication().getDataLocation() + "/correction");

            String select = 
                "select " +
                "id AS ID, " +

                ....
                "is_automated_month AS IS_AUTOMATED_MONTH " +
                "from maildepot_correction where approval_granted = 1 and is_payed = 0 order by id desc";
            
            rs = db.selectQuery(select);
            
            StringBuffer line;
            
            line = new StringBuffer();

            int rsId                = rs.findColumn("ID");
            ...
            int rsIsAutomatedMonth  = rs.findColumn("IS_AUTOMATED_MONTH");

            while (rs.next()) {

                line.setLength(0);

                // Fields maildepot_correction export file
                // 01. id
                line.append(rs.getString(rsId));
                line.append(CSVWriter.SEMICOLON);
                ....
                // 22. is_automated_month
                line.append(rs.getString(rsIsAutomatedMonth));
                
                writer.addRecord(line.toString());                
            }
            
        } catch (Exception e) {

            if (writer != null) {
                writer.clean();
            }

            throw e;

        } finally {

            try {
                if (writer != null) {
                    writer.close();
                }
                if (rs != null) {
                    rs.getStatement().close();
                }
            } catch (IOException ioe) {
                logger.error("getMaildepotCorrectionFile()", ioe);
            }                         
        }
        
        return writer;
                        
    }
}


Sorry dat de code zo lang is. Ik wou alleen de 2 methodes laten zien waar het csv bestand aangemaakt en opgeslagen wordt.
Wat is de beste manier om die geval te tackelen? Welke onderdeel van Java kan ik hiervoor gebruiken?

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Wat dacht je ervan om de file naar de response te schrijven?

Iets in de aard van:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void writeFileToResponse(HttpServletResponse res, File downloadFile){
        log.debug("Writing file to response...");       
                
        res.setHeader("Content-length", Long.toString(downloadFile.length()));
        // We plaatsen een niet-gekende content-type in de header.
        // Op deze manier toont de browser altijd de dialog.
        res.setHeader("Content-type","application/x-download");
        res.setHeader("Content-disposition","attachment; filename=" + downloadFile.getName() );
        try {   
            BufferedInputStream download = new BufferedInputStream(new FileInputStream(downloadFile));
            write(res.getOutputStream(), download, 4*1024); // 4K Buffer
        }
        catch (FileNotFoundException e1) {
            log.error(e1);
        }
        catch (IOException e2) {
            log.error(e2);                  
        }
}

  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
Is die write methode een onderdeel van de FileHandler?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-04 22:57

Janoz

Moderator Devschuur®

!litemod

write is gewoon een methode die in elke writer of outputstream terug komt. Wanneer je wat naar de client wilt sturen zul je dat in je response weg moeten schrijven.

Wat ikzelf een beetje vreemd vind aan je geposte code is dat de CSVWriter class eigenlijk een CSVWriter met FileWriter is. Ik zou het logischer vinden wanneer deze twee functionaliteiten los zaten, dan kon je de CSVWriter rechtstreeks aan de outputstream van je response hangen (of eventueel eerst naar een string of bytearray zodat je de lengte kon bepalen).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
Jij hebt wel gelijk, maar CSVWriter is eenmaal een "gegeven" die ik moet gebruik voor het genereren van csv docs.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-04 22:57

Janoz

Moderator Devschuur®

!litemod

Dan zou ik gewoon de tempfile functionaliteit van File gebruiken voor het wegschrijven. Zoals je het nu hebt staan kom je in de problemen wanneer 2 mensen tegelijk een CSV bestand opvragen. Dit bestand vervolgens weer inlezen en wegschrijven naar de outputstream met de juiste headers. Hoe je dat wegschrijven doet kun je wel in de voorbeeldcode van FOX zien.

[ Voor 17% gewijzigd door Janoz op 18-11-2005 09:49 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • momania
  • Registratie: Mei 2000
  • Laatst online: 16:10

momania

iPhone 30! Bam!

turkosh schreef op vrijdag 18 november 2005 @ 09:22:
Jij hebt wel gelijk, maar CSVWriter is eenmaal een "gegeven" die ik moet gebruik voor het genereren van csv docs.
Heeft die CSVWriter dan alleen maar een constructor met een String als parameter?
Of kan je ook gewoon een OutputStream meegeven?

Anders idd de temp file functionaliteit gebruiken :)
Java:
1
String tmpDir = System.getProperty("java.io.tmpdir");

:)

Neem je whisky mee, is het te weinig... *zucht*


Verwijderd

momania schreef op vrijdag 18 november 2005 @ 09:58:
Anders idd de temp file functionaliteit gebruiken :)
Java:
1
String tmpDir = System.getProperty("java.io.tmpdir");

:)
Inderdaad de tempfile functionaliteit:
File.createTempFile(String, String)

  • momania
  • Registratie: Mei 2000
  • Laatst online: 16:10

momania

iPhone 30! Bam!

Ja, maar als hij met de CSVWriter alleen maar een path op kan geven heeft hij niet de mogenlijk om zelf die File aan te maken via createTempFile ;)

Neem je whisky mee, is het te weinig... *zucht*


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-04 22:57

Janoz

Moderator Devschuur®

!litemod

Ikzelf dacht ook meer aan de oplossing van Mark. Deze maakt ook gebruik van die system property, maar heeft daarnaast de garantie dat er een unieke naam aan het bestand gegeven wordt dat nog niet in die directory bestaat, vervolgens kun je met file.getAbsolutePath wel weer de string krijgen om het bestand vol te schrijven.

[ Voor 19% gewijzigd door Janoz op 18-11-2005 10:17 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
even meer inzicht geven in CSVWriter:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public class CSVWriter {

    /** Logger */
//    static final Logger logger = Logger.getLogger(CSVWriter.class);

    /** csv seperator comma ',' */
    public static final String COMMA = ",";
    /** csv seperator semicolon ';' */
    public static final String SEMICOLON = ";";
    /** Line separator LF (linefeed) */
    public static final String LINE_SP_LF = "\n";
    /** Line separator CRLF (control-linefeed) */
    public static final String LINE_SP_CRLF = "\r\n";

    private Vector<?> records;
    private int length;
    private int lines;
    
    private TempFileHandler tempFile;
    private FileOutputStream fileOutputStream;
    
    /**
     * Constructor for CSVWriter
     * @param path Temporary path
     */
    public CSVWriter(String path) throws SecurityException, IOException {

        super();

        length = 0;
        lines = 0;
        records = new Vector<Object>(0,5);

        tempFile = new TempFileHandler(path); //Hier zit dus ook de createTempFile() in
        tempFile.create("CSVWriter", ".csv");
        
        fileOutputStream = new FileOutputStream(tempFile.getFile());

    }

    /**
     * Add record to csv
     * 
     * @param line
     */
    public void addRecord(String line) throws IOException{
    .....   
    }
    
    /**
     * Get number of lines
     * 
     * @return Number of lines
     */
    public int getLines() {
    .....
    }
    
    /**
     * Close output
     * 
     * @throws IOException
     */
    public void close() throws IOException {
    .....
    }
    
    /**
     * Get csv file
     * 
     * @return Temporary file
     */
    public File getFile() {
    .....
    }
    
    /**
     * Clean up csvWriter data
     *
     */
    public void clean() {
    .....
    }
    
    
    /**
     * Get csv content as byte array
     * 
     * @return content of all csv records
     */
    public byte[] getBytes() {
    .....
    }

[ Voor 5% gewijzigd door turkosh op 18-11-2005 10:31 ]


  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
Wat FOX gebruikt voor oplossing is de HttpServletResponse. In de servlets bij ons wordt gebruik gemaakt van ServletResponse die de setHeader() functionaliteit niet hebben

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-04 22:57

Janoz

Moderator Devschuur®

!litemod

hmm, een beetje een vreemde ontwerp beslissing dat dit object perse een file wil schrijven, maar met de getBytes methode kun je je probleem trouwens redelijk simpel oplossen.


----

Waarom gebruiken jullie geen httpServletResponse? Hebben jullie geen webapplicatie?

Het versturen van een bestand waardoor de gebruiker deze op kan slaan is een functionaliteit van het HTTP protocol. Zonder gebruik te maken van HttpServletResponse kun je die extra HTTP functionaliteiten helemaal niet gebruiken.

Als ik dit allemaal zo lees zou het nog best wel eens een idee kunnen zijn om de framework code bij jullie eens te voorzien van een flinke update...

[ Voor 64% gewijzigd door Janoz op 18-11-2005 10:44 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
je hebt gelijk. Heb de code inmiddels aangepast om te werken met httpservlet

  • turkosh
  • Registratie: December 2003
  • Laatst online: 26-04-2025
Eurekaaaaaaaaaaaa _/-\o_
Hij werkt!!!!
Bedankt allemaal
Pagina: 1