java對csv文件解析工具類


引用: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;
    }


}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM