14
14
15
15
/**
16
16
* CSV 转换程 excel
17
+ * CSV文件规则
18
+ * 1 开头是不留空,以“行”为单位。
19
+ * 2 可含或不含列名,含列名则居文件第一行。
20
+ * 3 一行数据不跨行,无空行。
21
+ * 4 以半角逗号(即,)作分隔符,列为空也要表达其存在。
22
+ * 5 列内容如存在半角逗号(即,)则用半角双引号(即"")将该字段值包含起来。
23
+ * 6 列内容如存在半角引号(即")则应替换成半角双引号("")转义,并用半角引号(即"")将该字段值包含起来。
24
+ * 7 文件读写时引号,逗号操作规则互逆。
25
+ * 8 内码格式不限,可为 ASCII、Unicode 或者其他。
26
+ * 9 不支持特殊字符
17
27
*
18
28
* @author drew
19
29
* @date 2021/2/23 10:32
@@ -37,8 +47,7 @@ public static CsvUtil getInstance() {
37
47
}
38
48
39
49
public static void main (String [] args ) throws Exception {
40
-
41
- // testReadCsv();
50
+ testReadCsv ();
42
51
// testExportCsv();
43
52
// testExportCsvPlus();
44
53
}
@@ -51,7 +60,7 @@ private static void testReadCsv() {
51
60
if ("exit" .equals (in )) {
52
61
break ;
53
62
}
54
- System .out .println ("文件的数据如下:\n " + JSONObject .toJSONString (readCsv (in , false )));
63
+ System .out .println ("文件的数据如下:\n " + JSONObject .toJSONString (readCsv (in , true )));
55
64
}
56
65
}
57
66
@@ -116,35 +125,113 @@ public static void saveFile(String filePath, byte[] data) {
116
125
/**
117
126
* 读取csv文件的数据
118
127
*
119
- * @param csvFilePath csv文件所在位置(例如:“D:\评价数据.csv”)
120
- * @param isNeedHeader true需要,false不需要
128
+ * @param csvFilePath csv文件所在位置(例如:“D:\评价数据.csv”)
129
+ * @param isHasHeader true第一行存在数据表头,false第一行不存在数据表头
121
130
* @return 数据集合
122
131
*/
123
- public static List < List < Object >> readCsv (String csvFilePath , boolean isNeedHeader ) {
124
- List < List < Object >> result = new ArrayList <>();
132
+ public static Map < String , Object > readCsv (String csvFilePath , boolean isHasHeader ) {
133
+ Map < String , Object > result = new HashMap <>(2 );
125
134
try {
126
135
// 中文乱码问题:源文件的编码格式与程序设置的读取格式不一致所致(调整csv文件为UTF-8集合)
127
136
DataInputStream in = new DataInputStream (new FileInputStream (csvFilePath ));
128
137
BufferedReader reader = new BufferedReader (new InputStreamReader (in , "gbk" ));
129
- if (!isNeedHeader ) {
130
- //第一行信息,为标题信息,不用,如果需要,注释掉
131
- reader .readLine ();
138
+ //第一行信息,为标题信息,不用,如果需要,注释掉
139
+ // reader.readLine();
140
+ if (isHasHeader ) {
141
+ result .put ("header" , reader .readLine ());
132
142
}
133
- String line = null ;
143
+ String line ;
144
+ List <List <String >> dataList = new ArrayList <>();
134
145
while ((line = reader .readLine ()) != null ) {
135
- //CSV格式文件为逗号分隔符文件,这里根据逗号切分
136
- List <Object > item = Arrays .asList (line .split ("," ));
137
- if (!ObjectUtils .isEmpty (item )) {
138
- // TODO 针对item集合中的每一个数据,可以进行具体类型转换(例如转称 integer类型,string类型,集合set/list类型等)
139
- result .add (item );
146
+ String [] parts = splitCSV (line );
147
+ if (!ObjectUtils .isEmpty (parts )){
148
+ List <String > lineData = Arrays .asList (parts );
149
+ dataList .add (lineData );
140
150
}
141
151
}
142
- } catch (IOException e ) {
143
- e .printStackTrace ();
152
+ result .put ("data" , dataList );
153
+ } catch (Exception exception ) {
154
+ exception .printStackTrace ();
144
155
}
145
156
return result ;
146
157
}
147
158
159
+ public static void test () {
160
+ String src1 = "\" fh,zg\" ,sdf,\" asfs,\" ,\" ,dsdf\" ,\" aadf\" \" \" ,\" \" \" hdfg\" ,\" fgh\" \" dgnh\" ,hgfg'dfh,\" asdfa\" \" \" \" \" ,\" \" \" \" \" fgjhg\" ,\" gfhg\" \" \" \" hb\" " ;
161
+ try {
162
+ String [] Ret = splitCSV (src1 );
163
+ for (int i = 0 ; i < Ret .length ; i ++) {
164
+ System .out .println (i + ": " + Ret [i ]);
165
+ }
166
+ } catch (Exception e ) {
167
+ e .printStackTrace ();
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Split one line of csv file
173
+ *
174
+ * @return a String array results
175
+ */
176
+ public static String [] splitCSV (String src ) throws Exception {
177
+ if (src == null || src .equals ("" )) {
178
+ return new String [0 ];
179
+ }
180
+ StringBuffer st = new StringBuffer ();
181
+ Vector result = new Vector ();
182
+ boolean beginWithQuote = false ;
183
+ for (int i = 0 ; i < src .length (); i ++) {
184
+ char ch = src .charAt (i );
185
+ if (ch == '\"' ) {
186
+ if (beginWithQuote ) {
187
+ i ++;
188
+ if (i >= src .length ()) {
189
+ result .addElement (st .toString ());
190
+ st = new StringBuffer ();
191
+ beginWithQuote = false ;
192
+ } else {
193
+ ch = src .charAt (i );
194
+ if (ch == '\"' ) {
195
+ st .append (ch );
196
+ } else if (ch == ',' ) {
197
+ result .addElement (st .toString ());
198
+ st = new StringBuffer ();
199
+ beginWithQuote = false ;
200
+ } else {
201
+ throw new Exception ("Single double-quote char mustn't exist in filed " + (result .size () + 1 ) + " while it is begined with quote\n char at:" + i );
202
+ }
203
+ }
204
+ } else if (st .length () == 0 ) {
205
+ beginWithQuote = true ;
206
+ } else {
207
+ throw new Exception ("Quote cannot exist in a filed which doesn't begin with quote!\n field:" + (result .size () + 1 ));
208
+ }
209
+ } else if (ch == ',' ) {
210
+ if (beginWithQuote ) {
211
+ st .append (ch );
212
+ } else {
213
+ result .addElement (st .toString ());
214
+ st = new StringBuffer ();
215
+ beginWithQuote = false ;
216
+ }
217
+ } else {
218
+ st .append (ch );
219
+ }
220
+ }
221
+ if (st .length () != 0 ) {
222
+ if (beginWithQuote ) {
223
+ throw new Exception ("last field is begin with but not end with double quote" );
224
+ } else {
225
+ result .addElement (st .toString ());
226
+ }
227
+ }
228
+ String rs [] = new String [result .size ()];
229
+ for (int i = 0 ; i < rs .length ; i ++) {
230
+ rs [i ] = (String ) result .elementAt (i );
231
+ }
232
+ return rs ;
233
+ }
234
+
148
235
/**
149
236
* 导出生成csv格式的文件
150
237
*
0 commit comments