引用:https://blog.csdn.net/hantiannan/article/details/6756347
可自動過濾單元格含換行字符或英文逗號的情況
public class CsvParser { private BufferedReader bufferedreader = null; private List<String> list = new ArrayList(); public CsvParser() { } public CsvParser(InputStream inStream) throws Exception { InputStreamReader isr = new InputStreamReader(inStream, "GBK"); bufferedreader = new BufferedReader(isr); String stemp; while ((stemp = readLine()) != null) { list.add(stemp); } } /** * 過濾回車和英文逗號 * * @return * @throws Exception */ public String readLine() throws Exception { StringBuilder readLine = new StringBuilder(); boolean bReadNext = true; while (bReadNext) { //換行符替換 if (readLine.length() > 0) { readLine.append("\r\n"); } // 一行 String strReadLine = bufferedreader.readLine(); // readLine is Null if (strReadLine == null) { return readLine.length() <= 0 ? null : readLine.toString(); } readLine.append(strReadLine); // 如果雙引號是奇數的時候繼續讀取(含有換行時會添加雙引號,自帶的雙引號會轉為2個雙引號) if (countChar(readLine.toString(), '"', 0) % 2 == 1) { bReadNext = true; } else { bReadNext = false; } } return readLine.toString(); } /** *計算指定文字的個數。 * * @param str 文字列 * @param c 文字 * @param start 開始位置 * @return 個數 */ private int countChar(String str, char c, int start) { int i = 0; int index = str.indexOf(c, start); return index == -1 ? i : countChar(str, c, index + 1) + 1; } public List<String> getList() throws IOException { return list; }/** * csv文件的行數 * * @return */ public int getRowNum() { return list.size(); } /** * 取得指定行的值 * * @param index * @return */ public String getRow(int index) { if (this.list.size() != 0) { return (String) list.get(index); } else { return null; } } /** * 把CSV文件的一行轉換成字符串數組。不指定數組長度。 */ public List<String> fromCSVLinetoArray(String source) { if (source == null || source.length() == 0) { return Collections.emptyList(); } int currentPosition = 0; int maxPosition = source.length(); int nextComma = 0; List<String> rtnArray = new ArrayList(); while (currentPosition < maxPosition) { nextComma = nextComma(source, currentPosition); rtnArray.add(nextToken(source, currentPosition, nextComma)); currentPosition = nextComma + 1; if (currentPosition == maxPosition) { rtnArray.add(""); } } return rtnArray; } /** * 查詢下一個逗號的位置。 * * @param source 文字列 * @param st 檢索開始位置 * @return 下一個逗號的位置。 */ private int nextComma(String source, int st) { int maxPosition = source.length(); boolean inquote = false; while (st < maxPosition) { char ch = source.charAt(st); if (!inquote && ch == ',') { break; } else if ('"' == ch) { inquote = !inquote; } st++; } return st; } /** * 取得下一個字符串 */ private static String nextToken(String source, int st, int nextComma) { StringBuilder strb = new StringBuilder(); int next = st; while (next < nextComma) { char ch = source.charAt(next++); if (ch == '"') { if ((st + 1 < next && next < nextComma) && (source.charAt(next) == '"')) { strb.append(ch); next++; } } else { strb.append(ch); } } return strb.toString(); } /** * 獲取所有行(不含表頭) * * @return 行列表,且每行是一個列表 */ public List<List<String>> getRowsWithNoHeader() { List<List<String>> result = new ArrayList<List<String>>(); for (int i = 1; i < getRowNum(); i++) { String row = getRow(i); List<String> oneRow = this.fromCSVLinetoArray(row); if (CollectionUtils.isNotEmpty(oneRow)) { result.add(oneRow); } } return result; } }