]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CsvWriter.java
19086d613a8dafca5e6509bd1b27cc9486cb1572
[lgpl/argeo-commons.git] / CsvWriter.java
1 package org.argeo.util;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.io.PrintWriter;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import org.argeo.ArgeoException;
10
11 /** Write in CSV format. */
12 public class CsvWriter {
13 private final PrintWriter out;
14
15 private char separator = ',';
16 private char quote = '\"';
17
18 /**
19 * Creates a CSV writer. The header will be written immediately to the
20 * stream.
21 *
22 * @param out
23 * the stream to write to. Caller is responsible for closing it.
24 */
25 public CsvWriter(OutputStream out) {
26 super();
27 this.out = new PrintWriter(out);
28 }
29
30 /**
31 * Write a CSV line. Also used to write a header if needed (this is
32 * transparent for the CSV writer): simply call it first, before writing the
33 * lines.
34 */
35 public void writeLine(List<?> tokens) {
36 try {
37 Iterator<?> it = tokens.iterator();
38 while (it.hasNext()) {
39 writeToken(it.next().toString());
40 if (it.hasNext())
41 out.print(separator);
42 }
43 out.print('\n');
44 out.flush();
45 } catch (IOException e) {
46 throw new ArgeoException("Could not write " + tokens, e);
47 }
48 }
49
50 protected void writeToken(String token) throws IOException {
51 // +2 for possible quotes, another +2 assuming there would be an already
52 // quoted string where quotes needs to be duplicated
53 // another +2 for safety
54 StringBuffer buf = new StringBuffer(token.length() + 6);
55 char[] arr = token.toCharArray();
56 boolean shouldQuote = false;
57 for (char c : arr) {
58 if (!shouldQuote) {
59 if (c == separator)
60 shouldQuote = true;
61 if (c == '\n')
62 shouldQuote = true;
63 }
64
65 if (c == quote) {
66 shouldQuote = true;
67 // duplicate quote
68 buf.append(quote);
69 }
70
71 // generic case
72 buf.append(c);
73 }
74
75 if (shouldQuote == true)
76 out.print(quote);
77 out.print(buf.toString());
78 if (shouldQuote == true)
79 out.print(quote);
80 }
81 }