zoukankan      html  css  js  c++  java
  • Java之CSV文件转List数据工具

    借鉴博客:https://www.cnblogs.com/yybinger/p/11907193.html

    工具文件,可直接调用,亲测有效:

    package com.powersi.biz.park.network.util;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @Description TODO
     * @Author zhouruntao
     * @Date 2020/11/11 11:18
     */
    public class CsvToListUtil {
    
        /**
         * CSV文件编码
         */
        private static final String ENCODE = "UTF-8";
    
        /**
         * 读取CSV文件得到List,默认使用UTF-8编码
         * @param fileName 文件路径
         * @return
         */
        public static List<String> getLines(String fileName) {
            return getLines(fileName, ENCODE);
        }
    
        /**
         * 读取CSV文件得到List
         * @param fileName 文件路径
         * @param encode 编码
         * @return
         */
        public static List<String> getLines(String fileName, String encode) {
            List<String> lines = new ArrayList<String>();
            BufferedReader br = null;
            InputStreamReader isr = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(fileName);
                isr = new InputStreamReader(fis, encode);
                br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine()) != null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(line);
                    boolean readNext = countChar(sb.toString(), '"', 0) % 2 == 1;
                    // 如果双引号是奇数的时候继续读取。考虑有换行的是情况
                    while (readNext) {
                        line = br.readLine();
                        if (line == null) {
                            return null;
                        }
                        sb.append(line);
                        readNext = countChar(sb.toString(), '"', 0) % 2 == 1;
                    }
                    lines.add(sb.toString());
                }
            } catch (Exception e) {
    //            log.error("Read CSV file failure :{}", e);
                System.out.println("Read CSV file failure :{}" + e);
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                    if (isr != null) {
                        isr.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
    //                log.error("Close stream failure :{}", e);
                    System.out.println("Close stream failure :{}" + e);
                }
            }
            return lines;
        }
    
        public static List<String> getLines(File file, String encode) {
            List<String> lines = new ArrayList<String>();
            BufferedReader br = null;
            InputStreamReader isr = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file);
                isr = new InputStreamReader(fis, encode);
                br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine()) != null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(line);
                    boolean readNext = countChar(sb.toString(), '"', 0) % 2 == 1;
                    // 如果双引号是奇数的时候继续读取。考虑有换行的是情况
                    while (readNext) {
                        line = br.readLine();
                        if (line == null) {
                            return null;
                        }
                        sb.append(line);
                        readNext = countChar(sb.toString(), '"', 0) % 2 == 1;
                    }
                    lines.add(sb.toString());
                }
            } catch (Exception e) {
    //            log.error("Read CSV file failure :{}", e);
                System.out.println("Read CSV file failure :{}" + e);
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                    if (isr != null) {
                        isr.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
    //                log.error("Close stream failure :{}", e);
                    System.out.println("Close stream failure :{}" + e);
                }
            }
            return lines;
        }
    
        public static String[] fromCSVLine(String source) {
            return fromCSVLine(source, 0);
        }
    
        /**
         * 把CSV文件的一行转换成字符串数组。指定数组长度,不够长度的部分设置为null
         * @param source
         * @param size
         * @return
         */
        public static String[] fromCSVLine(String source, int size) {
            List list = fromCSVLineToArray(source);
            if (size < list.size()) {
                size = list.size();
            }
            String[] arr = new String[size];
            list.toArray(arr);
            return arr;
        }
    
        public static List fromCSVLineToArray(String source) {
            if (source == null || source.length() == 0) {
                return new ArrayList();
            }
            int currentPosition = 0;
            int maxPosition = source.length();
            int nextComa = 0;
            List list = new ArrayList();
            while (currentPosition < maxPosition) {
                nextComa = nextComma(source, currentPosition);
                list.add(nextToken(source, currentPosition, nextComa));
                currentPosition = nextComa + 1;
                if (currentPosition == maxPosition) {
                    list.add("");
                }
            }
            return list;
        }
    
        /**
         * 把字符串类型的数组转换成一个CSV行。(输出CSV文件的时候用)
         *
         * @param arr
         * @return
         */
        public static String toCSVLine(String[] arr) {
            if (arr == null) {
                return "";
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                String item = addQuote(arr[i]);
                sb.append(item);
                if (arr.length - 1 != i) {
                    sb.append(",");
                }
            }
            return sb.toString();
        }
    
        /**
         * 将list的第一行作为Map的key,下面的列作为Map的value
         * @param list
         * @return
         */
        public static List<Map<String, String>> parseList(List<String> list) {
            List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
            String firstLine = list.get(0);
            String[] fields = firstLine.split(",");
            for (int i = 1; i < list.size(); i++) {
                String valueLine = list.get(i);
                String[] valueItems = CsvToListUtil.fromCSVLine(valueLine);
                Map<String, String> map = new HashMap<String, String>();
                for (int j = 0; j < fields.length; j++) {
                    map.put(fields[j], valueItems[j]);
                }
                resultList.add(map);
            }
            return resultList;
        }
    
        /**
         * 字符串类型的List转换成一个CSV行。(输出CSV文件的时候用)
         *
         * @param strArrList
         * @return
         */
        public static String toCSVLine(ArrayList strArrList) {
            if (strArrList == null) {
                return "";
            }
            String[] strArray = new String[strArrList.size()];
            for (int idx = 0; idx < strArrList.size(); idx++) {
                strArray[idx] = (String) strArrList.get(idx);
            }
            return toCSVLine(strArray);
        }
    
        /**
         * 计算指定字符的个数
         *
         * @param str   文字列
         * @param c     字符
         * @param start 开始位置
         * @return 个数
         */
        private static int countChar(String str, char c, int start) {
            int index = str.indexOf(c, start);
            return index == -1 ? 0 : countChar(str, c, index + 1) + 1;
        }
    
        /**
         * 查询下一个逗号的位置。
         *
         * @param source 文字列
         * @param st     检索开始位置
         * @return 下一个逗号的位置。
         */
        private static 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;
        }
    
        /**
         * 取得下一个字符串
         *
         * @param source
         * @param st
         * @param nextComma
         * @return
         */
        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();
        }
    
        /**
         * 在字符串的外侧加双引号。如果该字符串的内部有双引号的话,把"转换成""。
         *
         * @param item 字符串
         * @return 处理过的字符串
         */
        private static String addQuote(String item) {
            if (item == null || item.length() == 0) {
                return """";
            }
            StringBuilder sb = new StringBuilder();
            sb.append('"');
            for (int idx = 0; idx < item.length(); idx++) {
                char ch = item.charAt(idx);
                if ('"' == ch) {
                    sb.append("""");
                } else {
                    sb.append(ch);
                }
            }
            sb.append('"');
            return sb.toString();
        }
    
    }

    我的调用(我重写了getLines方法,因为我这里要传file文件,而不是传文件路径):

    //调用CSV文件转List工具
            List<String> lines = CsvToListUtil.getLines(file, "GBK");
            List<Map<String, String>> mapList = CsvToListUtil.parseList(lines);
            System.out.println(Arrays.toString(mapList.toArray()));

    。。。

  • 相关阅读:
    消息中间件——RabbitMQ(一)Windows/Linux环境搭建(完整版)
    数据结构与算法(一):带你了解时间复杂度和空间复杂度到底是什么?
    作为一技术人员,面试前都需要做哪些准备?
    消息中间件——RocketMQ(一) 环境搭建(完整版)
    从“数学归纳法”到理解“递归算法”!
    深入浅出了解“装箱与拆箱”
    PMP备考指南之第二章:项目运作环境
    PMP备考指南之第一章:引论
    PMP备考指南之相关事项介绍
    7月新的开始
  • 原文地址:https://www.cnblogs.com/spll/p/13957926.html
Copyright © 2011-2022 走看看