Skip to content

Commit 8e9bb18

Browse files
committed
refactor: 完善工具类(csv数据正确读取)
1 parent 1644275 commit 8e9bb18

File tree

1 file changed

+105
-18
lines changed
  • springboot-aop/src/main/java/com/study/module/util/office

1 file changed

+105
-18
lines changed

springboot-aop/src/main/java/com/study/module/util/office/CsvUtil.java

Lines changed: 105 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414

1515
/**
1616
* CSV 转换程 excel
17+
* CSV文件规则
18+
* 1 开头是不留空,以“行”为单位。
19+
* 2 可含或不含列名,含列名则居文件第一行。
20+
* 3 一行数据不跨行,无空行。
21+
* 4 以半角逗号(即,)作分隔符,列为空也要表达其存在。
22+
* 5 列内容如存在半角逗号(即,)则用半角双引号(即"")将该字段值包含起来。
23+
* 6 列内容如存在半角引号(即")则应替换成半角双引号("")转义,并用半角引号(即"")将该字段值包含起来。
24+
* 7 文件读写时引号,逗号操作规则互逆。
25+
* 8 内码格式不限,可为 ASCII、Unicode 或者其他。
26+
* 9 不支持特殊字符
1727
*
1828
* @author drew
1929
* @date 2021/2/23 10:32
@@ -37,8 +47,7 @@ public static CsvUtil getInstance() {
3747
}
3848

3949
public static void main(String[] args) throws Exception {
40-
41-
// testReadCsv();
50+
testReadCsv();
4251
// testExportCsv();
4352
// testExportCsvPlus();
4453
}
@@ -51,7 +60,7 @@ private static void testReadCsv() {
5160
if ("exit".equals(in)) {
5261
break;
5362
}
54-
System.out.println("文件的数据如下:\n" + JSONObject.toJSONString(readCsv(in, false)));
63+
System.out.println("文件的数据如下:\n" + JSONObject.toJSONString(readCsv(in, true)));
5564
}
5665
}
5766

@@ -116,35 +125,113 @@ public static void saveFile(String filePath, byte[] data) {
116125
/**
117126
* 读取csv文件的数据
118127
*
119-
* @param csvFilePath csv文件所在位置(例如:“D:\评价数据.csv”)
120-
* @param isNeedHeader true需要,false不需要
128+
* @param csvFilePath csv文件所在位置(例如:“D:\评价数据.csv”)
129+
* @param isHasHeader true第一行存在数据表头,false第一行不存在数据表头
121130
* @return 数据集合
122131
*/
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);
125134
try {
126135
// 中文乱码问题:源文件的编码格式与程序设置的读取格式不一致所致(调整csv文件为UTF-8集合)
127136
DataInputStream in = new DataInputStream(new FileInputStream(csvFilePath));
128137
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());
132142
}
133-
String line = null;
143+
String line;
144+
List<List<String>> dataList = new ArrayList<>();
134145
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);
140150
}
141151
}
142-
} catch (IOException e) {
143-
e.printStackTrace();
152+
result.put("data", dataList);
153+
} catch (Exception exception) {
154+
exception.printStackTrace();
144155
}
145156
return result;
146157
}
147158

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\nchar 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!\nfield:" + (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+
148235
/**
149236
* 导出生成csv格式的文件
150237
*

0 commit comments

Comments
 (0)