Bootstrap

Java csv文件的读取和写入,拒绝中文乱码

目录

一、场景:

二、避坑指南:

三、简单版读写代码:

1、csv写入

2、读取

四、commons-csv版读写代码:

1.引入pom(使用1.9.0版本)

2.API应用 

2.1.写入

2.2读取

五、结语


一、场景:

在对数据进行导出时,发现导出为Excel会导致服务器内存溢出,经排查,是因为导出为Excel时,每个单元格都会先存放到内存里,单元格太多导致内存溢出,所以改用为csv文件导出。

二、避坑指南:

1.csv文件的分隔符是可指定的,一般默认为英文逗号“,”,想要单元格样式的分隔符,需要引入common-csv jar包;
2.csv文件的编码格式要特别注意,否则导出来数据就是乱码。

三、简单版读写代码:

1、csv写入

/**
 * 写入CSV,csv文件分隔符,默认“,”
 *
 * @param filePath        csv文件路径
 * @param list 数据集
 * @param  charsetName,默认GBK
 * @return
 */
public static void writeCSV(String filePath, List<String> list,String charsetName) {
    try {
        if (ValidateUtils.isEmpty(charsetName)) {
            charsetName = "GBK";
        }
        OutputStreamWriter outputStreamWriter =
                new OutputStreamWriter(new FileOutputStream(filePath), charsetName);
        BufferedWriter writer = new BufferedWriter(outputStreamWriter);
        for (String s : list) {
            writer.write(s);
            writer.newLine();
        }
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2、读取

/**
     * 读取
     *
     * @param path        csv文件路径
     * @param csvSplit    csv文件分隔符,默认“,”
     * @param charsetName csv文件编码格式,默认GBK
     * @return
     */
    public static List<Map<String, String>> readCsv(String path, String csvSplit, String charsetName) throws IOException {
        List<Map<String, String>> results = new ArrayList<>();
        BufferedReader bReader = null;
        File file = new File(path);
        if (ValidateUtils.isEmpty(charsetName)) {
            charsetName = "GBK";
        }
        try {
            bReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
            String line = "";
            //忽略第一行标题
            List<String> titles = new ArrayList<>();
            String titleArr[] = bReader.readLine().split(csvSplit);
            for (String title : titleArr) {
                titles.add(title);
            }
            while ((line = bReader.readLine()) != null) {
                if (line.trim() != "") {
                    //分割开来的即是对应的每个单元格,注意空的情况
                    String valueArr[] = line.split(csvSplit);
                    int valueLength = valueArr.length;
                    Map<String, String> result = new HashMap<>();
                    for (int i = 0; i < titles.size(); i++) {
                        String title = titles.get(i);
                        String value = "";
                        if (i < valueLength) {
                            value = valueArr[i];
                        } else
                            value = null;
                        result.put(title, value);
                    }
                    results.add(result);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (bReader != null) {
                bReader.close();
            }
        }
        return results;
    }

四、commons-csv版读写代码:

1.引入pom(使用1.9.0版本)

 <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-csv</artifactId>
            <version>1.9.0</version>
  </dependency>

2.API应用 

2.1.写入

/**
     * @Description: convert list<Map<>> to csv
     * @Param: headerList,valueList,pathName
     * @return:
     */
    public static void writeCsv(List<String> headerList,List<Map<String,String>> valueList,String pathName)  {
        try  {
            OutputStreamWriter outputStreamWriter =
                    new OutputStreamWriter(new FileOutputStream(pathName), "GBK");
            BufferedWriter writer = new BufferedWriter(outputStreamWriter);
            CSVPrinter printer = new CSVPrinter(writer, CSVFormat.EXCEL);
            printer.printRecord(headerList);
            for(Map<String,String> map : valueList) {
                List<String> values = new ArrayList<>();
                for(String header : headerList)
                    values.add(map.get(header));
                printer.printRecord(values);
            }
            printer.close();
            writer.close();
            outputStreamWriter.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

2.2读取

/**
     * 读取,csv文件编码格式,默认GBK,可自己修改,拒绝中文乱码
     *
     * @param path csv文件路径
     * 
     * @return
     */
public static JSONObject readCsv(String fileName) {
        JSONObject results = new JSONObject();
        try {
            File file = new File(fileName);
            BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GBK"));
            CSVParser parser = CSVFormat.DEFAULT.parse(bReader);
            //标题
            List<String> titles = new ArrayList<>();
            List<CSVRecord> records = parser.getRecords();
            if (records!=null && records.size()>0){
                CSVRecord titleRecord = records.get(0);
                for (int i = 0; i < titleRecord.size(); i++) {
                    titles.add(titleRecord.get(i));
                }
                results.put("title",titles);
            }
            if (records.size()>1){
                List<Map<String, String>> values = new ArrayList<>();
                for (int i = 1; i < records.size(); i++) {
                    CSVRecord record = records.get(i);
                    Map<String, String> map = new HashMap<>();
                    for (int j = 0; j < record.size(); j++) {
                        String value = record.get(j);
                        String title = titles.get(j);
                        map.put(title,value);
                    }
                    values.add(map);
                }
                results.put("values",values);
            }
            parser.close();
            bReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return results;
    }

五、结语

实际工作中,很多数据都存在csv文件中,使用 java语言开发的时候,有的时候需要读取文件,或者将csv文件导入到数据库中,commons-csv作为三方类库,简化了读取操作!

欢迎留言讨论!

;