Java 용 CSV API [닫기]


164

누구나 CSV 입력 파일을 읽고, 간단한 변환을 한 다음, 쓸 수있는 간단한 API를 추천 할 수 있습니까?

빠른 Google이 http://flatpack.sourceforge.net/ 을 찾았습니다 .

이 API에 자신을 연결하기 전에 다른 사람들이 무엇을 사용하고 있는지 확인하고 싶었습니다.


소프트웨어 라이브러리에 대한 제안을 요청할 때는 자매 사이트 소프트웨어 권장 사항 스택 교환을 사용하십시오 . 가지고 자바 및 CSV에 대한 몇 가지 안타를 .
Basil Bourque

답변:


32

아파치 커먼즈 CSV

Apache Common CSV를 확인하십시오 .

이 라이브러리 는 표준 RFC 4180을 포함하여 몇 가지 변형 된 CSV를 읽고 씁니다 . 또한 탭으로 구분 된 파일을 읽거나 씁니다 .

  • 뛰어나다
  • InformixUnload
  • InformixUnloadCsv
  • MySQL
  • 신탁
  • PostgreSQLCsv
  • PostgreSQL 텍스트
  • RFC4180
  • TDF

샌드 박스 된 Commons CSV를 꽤 오랫동안 사용해 왔으며 문제가 발생하지 않았습니다. 나는 그들이 그것을 완전히 서서 홍보하고 샌드 박스에서 꺼내기를 바랍니다.
Alex Marshall

3
@ bmatthews68 샌드 박스 링크가 사용되지 않습니다. 아파치 커먼즈 로 이동 한 것 같습니다 (답변의 링크도 편집했습니다)
drevicko


83

과거에는 OpenCSV 를 사용 했습니다 .

import au.com.bytecode.opencsv.CSVReader;

문자열 fileName = "data.csv";
CSVReader 리더 = 새로운 CSVReader (new FileReader (fileName));

// 첫 번째 줄이 머리글 인 경우 String [] 헤더 = reader.readNext ();
// null을 반환 할 때까지 reader.readNext를 반복합니다. String [] line = reader.readNext ();

다른 질문 에 대한 답변에는 다른 선택이있었습니다 .


불행히도 OpenCSV의 최신 다운로드 (댓글 달 때 v2.2)는 컴파일되지 않으며 사전 빌드 된 바이너리를 제공하지 않습니다.
opyate

9
SourceForge에서 다운로드 한 패키지는 deploy 폴더에 바이너리가있었습니다.
Mike Sickler 2018 년

8
maven을 사용하는 경우 공식 웹 사이트의 종속성 코드에는 버전 선언 "2.0"이 포함되어 있지만 버그가 있지만 리포지토리에는 버전 2.3이 업데이트되어 있습니다.
경계선

이 lib는 별도의 스레드에 파일을 쓰지 않습니다.
Ewoks

3
github.com/uniVocity/csv-parsers-comparison 에 따르면 uniVocity 보다 평균 73 % 느립니다.
Ewoks

32

업데이트 : 이 답변의 코드는 Super CSV 1.52 용입니다. Super CSV 2.4.0의 업데이트 된 코드 예제는 프로젝트 웹 사이트에서 찾을 수 있습니다. http://super-csv.github.io/super-csv/index.html


SuperCSV 프로젝트는 CSV 셀의 구문 분석 및 구조화 된 조작을 직접 지원합니다. 에서 http://super-csv.github.io/super-csv/examples_reading.html 찾을 수 있습니다 예를 들어,

수업이 주어졌다

public class UserBean {
    String username, password, street, town;
    int zip;

    public String getPassword() { return password; }
    public String getStreet() { return street; }
    public String getTown() { return town; }
    public String getUsername() { return username; }
    public int getZip() { return zip; }
    public void setPassword(String password) { this.password = password; }
    public void setStreet(String street) { this.street = street; }
    public void setTown(String town) { this.town = town; }
    public void setUsername(String username) { this.username = username; }
    public void setZip(int zip) { this.zip = zip; }
}

헤더가있는 CSV 파일이 있습니다. 다음 내용을 가정 해 봅시다

username, password,   date,        zip,  town
Klaus,    qwexyKiks,  17/1/2007,   1111, New York
Oufu,     bobilop,    10/10/2007,  4555, New York

그런 다음 UserBean의 인스턴스를 작성하고 다음 코드를 사용하여 파일의 두 번째 줄의 값으로 채울 수 있습니다.

class ReadingObjects {
  public static void main(String[] args) throws Exception{
    ICsvBeanReader inFile = new CsvBeanReader(new FileReader("foo.csv"), CsvPreference.EXCEL_PREFERENCE);
    try {
      final String[] header = inFile.getCSVHeader(true);
      UserBean user;
      while( (user = inFile.read(UserBean.class, header, processors)) != null) {
        System.out.println(user.getZip());
      }
    } finally {
      inFile.close();
    }
  }
}

다음의 "조작 사양"을 사용하는 것

final CellProcessor[] processors = new CellProcessor[] {
    new Unique(new StrMinMax(5, 20)),
    new StrMinMax(8, 35),
    new ParseDate("dd/MM/yyyy"),
    new Optional(new ParseInt()),
    null
};

1
코드가 컴파일되지 않았으므로 수정 사항을 제출했습니다. 또한 ParseDate ()가 올바르게 작동하지 않으므로 문자열을 읽도록 교체했습니다. 나중에 구문 분석 할 수 있습니다.

1
큰 제한 사항 : SuperCSV는 스레드 안전하지 않습니다. Jackson에 대해 살펴
보겠습니다.

SuperCsv는 멀티 맵 사용도 허용하지 않습니다. MultiMaps에서 작동하는 것이 좋을 것입니다.
Sid

19

CSV 형식 설명을 읽으면 타사 라이브러리를 사용하는 것이 직접 작성하는 것보다 두통이 적습니다.

Wikipedia에는 ​​10 가지 또는 알려진 라이브러리가 있습니다.

나는 일종의 검사 목록을 사용하여 나열된 라이브러리를 비교했습니다. OpenCSV 는 나에게 우승자 (YMMV)를 보냈 으며 다음과 같은 결과를 얻었습니다.

+ maven

+ maven - release version   // had some cryptic issues at _Hudson_ with snapshot references => prefer to be on a safe side

+ code examples

+ open source   // as in "can hack myself if needed"

+ understandable javadoc   // as opposed to eg javadocs of _genjava gj-csv_

+ compact API   // YAGNI (note *flatpack* seems to have much richer API than OpenCSV)

- reference to specification used   // I really like it when people can explain what they're doing

- reference to _RFC 4180_ support   // would qualify as simplest form of specification to me

- releases changelog   // absence is quite a pity, given how simple it'd be to get with maven-changes-plugin   // _flatpack_, for comparison, has quite helpful changelog

+ bug tracking

+ active   // as in "can submit a bug and expect a fixed release soon"

+ positive feedback   // Recommended By 51 users at sourceforge (as of now)

8

우리는 JavaCSV를 사용 하며 꽤 잘 작동합니다.


3
이 라이브러리의 유일한 문제는 Windows에서 \r\n실행되지 않을 때 Windows 줄 종결 자 ( )를 사용 하여 CSV 파일을 출력 할 수 없다는 것입니다 . 저자는 수년간 지원을 제공하지 않았습니다. 나는없는 기능을 할 수 있도록 그것을 포크로했다 : JavaCSV 2.2
MOSTY Mostacho에게

6

몇 달 전 주목할만한 양의 CSV를 처리하는 데 필요한 마지막 엔터프라이즈 응용 프로그램의 경우 sourceforge에서 SuperCSV 를 사용 하여 간단하고 강력하며 문제가없는 것으로 나타났습니다.


SuperCSV의 경우 +1이지만 아직 수정되지 않은 불쾌한 버그가 있으며 새로운 버그는 현재 처리되지 않으며 마지막 릴리스는 거의 2 년이되었습니다. 그러나 프로덕션 환경에서는 패치 / 수정 된 버전을 문제없이 사용하고 있습니다.
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1 이 최근에 릴리스되었습니다. 여기에는 많은 버그 수정 및 새로운 기능 (중첩 된 속성 및 배열 / 컬렉션 매핑을위한 Maven 지원 및 새로운 Dozer 확장 포함)이 포함되어 있습니다.
James Bassett

1
@ Hound-Dog 업데이트에 감사드립니다. 이미 새로운 베타 버전을 발견했으며 프로젝트가 계속 진행되는 것을 보게되어 기쁩니다. 커밋 빈도는 여전히 조금 겁이납니다 (거의 모든 커밋은 며칠 만). 하지만 살펴 보겠습니다. 최종 2.0의 출시 예정일이 있습니까?
MRalwasser

2
@MRalwasser 나는 현재 유일하게 개발자이며 풀 타임으로 일하고 있으므로 무료 주말을 가질 때 마다이 작업을하는 경향이 있습니다. 따라서 산발적 인 커밋 :) 거의 1000 개의 SF SF 다운로드 및 버그 없음, 다음 달 초에 최종 릴리스를 찾을 예정입니다. 향후 기능에 대한 아이디어가 있으면 알려주십시오.
James Bassett

1
SuperCSV는이 단계에서 스레드 안전하지 않으므로 실제로 강력하지 않습니다
ZiglioUK

5

csvreader api를 사용하고 다음 위치에서 다운로드 할 수 있습니다.

http://sourceforge.net/projects/javacsv/files/JavaCsv/JavaCsv%202.1/javacsv2.1.zip/download

또는

http://sourceforge.net/projects/javacsv/

다음 코드를 사용하십시오.

/ ************ For Reading ***************/

import java.io.FileNotFoundException;
import java.io.IOException;

import com.csvreader.CsvReader;

public class CsvReaderExample {

    public static void main(String[] args) {
        try {

            CsvReader products = new CsvReader("products.csv");

            products.readHeaders();

            while (products.readRecord())
            {
                String productID = products.get("ProductID");
                String productName = products.get("ProductName");
                String supplierID = products.get("SupplierID");
                String categoryID = products.get("CategoryID");
                String quantityPerUnit = products.get("QuantityPerUnit");
                String unitPrice = products.get("UnitPrice");
                String unitsInStock = products.get("UnitsInStock");
                String unitsOnOrder = products.get("UnitsOnOrder");
                String reorderLevel = products.get("ReorderLevel");
                String discontinued = products.get("Discontinued");

                // perform program logic here
                System.out.println(productID + ":" + productName);
            }

            products.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

CSV 파일에 쓰기 / 추가

암호:

/************* For Writing ***************************/

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.csvreader.CsvWriter;

public class CsvWriterAppendExample {

    public static void main(String[] args) {

        String outputFile = "users.csv";

        // before we open the file check to see if it already exists
        boolean alreadyExists = new File(outputFile).exists();

        try {
            // use FileWriter constructor that specifies open for appending
            CsvWriter csvOutput = new CsvWriter(new FileWriter(outputFile, true), ',');

            // if the file didn't already exist then we need to write out the header line
            if (!alreadyExists)
            {
                csvOutput.write("id");
                csvOutput.write("name");
                csvOutput.endRecord();
            }
            // else assume that the file already has the correct header line

            // write out a few records
            csvOutput.write("1");
            csvOutput.write("Bruce");
            csvOutput.endRecord();

            csvOutput.write("2");
            csvOutput.write("John");
            csvOutput.endRecord();

            csvOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}


2

CSV 형식은 StringTokenizer에 충분히 들리지만 더 복잡해질 수 있습니다. 여기서 독일에서는 세미콜론이 구분 기호로 사용되며 구분 기호가 포함 된 셀을 이스케이프해야합니다. StringTokenizer를 사용하면 쉽게 처리 할 수 ​​없습니다.

나는 http://sourceforge.net/projects/javacsv에 갈 것입니다


0

Excel에서 CSV를 읽으려는 경우 흥미로운 코너 사례가 있습니다. 나는 그것들을 모두 기억할 수는 없지만, apache commons csv는 그것을 올바르게 처리 할 수 ​​없었습니다 (예 : URL).

따옴표와 쉼표 및 슬래시를 사용하여 Excel 출력을 테스트하십시오.


아파치 코 몬즈 CSV의 라이브러리를 제공하지 Microsoft Excel에서의 특정 변종 . 그것이 당신이 언급 한 문제를 처리하는지 여부는 알 수 없습니다.
Basil Bourque
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.