首頁 > 軟體

Java實現將類資料逐行寫入CSV檔案的方法詳解

2022-11-09 14:02:20

1. 需求和思路

最近要用java製作一個資料集,每一行是一個樣本,格式是csv。用了一下java類的相關概念,把csv檔案裡的每一行,即每一個樣本視為一個類。

2. 現有方法

目前已有的csv包如opencsv,可以支援字串,也可以支援javabean(即java類)。相關教學如下

Java OpenCSV|極客教學

由於牆的原因,我maven老是下載不到opencsv的jar包,沒辦法我只能手寫個平民版的

3. 程式碼

自定義的CodeObject類

public class CodeObject {
    private String filePath;
    private String methodName;
    private String content;
 
    public void setFilePath(String filePath){ this.filePath = filePath;}
    public void setMethodName(String methodName) { this.methodName = methodName;}
    public void setContent(String content) { this.content = content;}
 
    public String getFilePath() { return filePath;}
    public String getMethodName() { return methodName;}
    public String getContent() { return content;}
}

mycsv類

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
 
public class mycsv {
    private File csvFile;
 
    public mycsv(String fileName){
        try {
            csvFile = new File(fileName);
            if (!csvFile.exists()){
                csvFile.createNewFile();
            }
        }catch (IOException e){
            System.out.println("error in io");
        }
    }
    public void writeCSVFile(String header[], ArrayList<CodeObject> cos){
        try{
            FileWriter fw  = new FileWriter(csvFile);
            BufferedWriter bw = new BufferedWriter(fw);
            // 寫表頭
            for (int i = 0; i < header.length; i++){
                if (i < header.length-1){
                    bw.append(header[i] + ",");
                }else{
                    bw.append(header[i] + "rn");
                }
            }
            // 寫資料
            for(CodeObject co: cos){
                bw.append(co.getFilePath()+",");
                bw.append(co.getMethodName()+",");
                bw.append(CSVFormatter(co.getContent())+"rn");
            }
            bw.close();
            fw.close();
        }catch (IOException e){
            System.out.println("error in io");
        }
    }
    public String CSVFormatter(String s){
        if (s == null) {
            return "";
        }
        if (s.contains(""")) {
            s = s.replaceAll(""", """");
        }
        return """ + s + """;
    }
}

呼叫方式

public static void main(String[] args) {
        ArrayList<CodeObject> methods = new ArrayList<>();
        /*
            一些操作將資料寫入methods中
        */
        String header[] = {"FilePath", "MethodName", "Content"};
        mycsv m = new mycsv("a.csv");
        m.writeCSVFile(header, methods);
}

4. 參考

因為我做的是把java檔案裡的方法切分開,每一個方法視為一個樣本,content的部分就是方法的程式碼。由於方法裡面有各種字元,如引號,直接寫入csv會出現錯位、序列、串列的問題。於是我在mycsv裡面加了一個CSVFormatter,這塊程式碼主要參考了下文。

Java處理CSV檔案中的換行符等字元

開發的時候需要匯出一批資料,為了方便使用的CSV格式。當時就只是簡單的用逗號分隔,但是因為部分欄位含有換行符、引號、逗號,導致用Excel開啟的時候部分資料錯位了,於是又將那幾個欄位處理了一下。

CSV檔案本質是一種用逗號和(回車)換行符分割的文字檔案,是可以直接中Excel開啟的。

處理方式就是在這個欄位前後新增雙引號,並且將欄位中原有的雙引號替換為兩個雙引號。

/**
 * @author pzzhao
 * @version 建立時間:2022-5-8 14:46
 */
public class CsvUtils {

    /**
     * @description: 處理csv檔案欄位中需要跳脫的引號
     *               新增雙引號,防止被欄位中的逗號和換行符干擾
     *               使其顯示為一個單元格
     * @param value 待處理的欄位值
     * @return: {@link String}
     * @author: pzzhao
     * @date: 2022-05-08 14:49:46
     */
    public static String processValueForCsv(String value) {
        if (value == null) {
            return "";
        }

        if (value.contains(""")) {
            value = value.replaceAll(""", """");
        }
         value = """ + value + """;

        return value;
    }
}

網上有很多現成的CSV工具類的,使用的時候建議還是使用成熟的工具類,也就不用操心這些跳脫字元的問題了。hutool 工具類裡就有現成的CsvUtil。我這個是懶得參照額外的包,所以就自己簡單處理了。

下面附上CSV檔案個規則:

  • 開頭是不留空,以行為單位。
  • 可含或不含列名,含列名則居檔案第一行。
  • 一行資料不跨行,無空行。
  • 以半形英文逗號(即,)作分隔符,列為空也要表達其存在。
  • 列內容如存在半形引號(即"),替換成半形雙引號(“”)跳脫,即用半形引號(即"")將該欄位值包含起來。
  • 檔案讀寫時引號,逗號操作規則互逆。
  • 內碼格式不限,可為 ASCII、Unicode 或者其他。
  • 不支援數位
  • 不支援特殊字元

到此這篇關於Java實現將類資料逐行寫入CSV檔案的方法詳解的文章就介紹到這了,更多相關Java類資料寫入CSV檔案內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com