API CSV cho Java [đã đóng]


164

Bất cứ ai cũng có thể đề xuất một API đơn giản cho phép tôi sử dụng đọc tệp đầu vào CSV, thực hiện một số biến đổi đơn giản và sau đó viết nó.

Một google nhanh chóng đã tìm thấy http://flatpack.sourceforge.net/ có vẻ đầy hứa hẹn.

Tôi chỉ muốn kiểm tra những gì người khác đang sử dụng trước khi tôi kết hợp với API này.


Sử dụng trang web chị em Phần mềm đề xuất trao đổi ngăn xếp khi yêu cầu đề xuất về thư viện phần mềm. Có nhiều lần truy cập cho Java & CSV .
Basil Bourque

Câu trả lời:


32

CSV Commons

Kiểm tra CSV chung của Apache .

Thư viện này đọc và ghi một số biến thể của CSV , bao gồm một RFC 4180 tiêu chuẩn . Cũng đọc / ghi các tệp được phân định bằng Tab .

  • Excel
  • Thông tin không tải
  • InformixUnloadCsv
  • MySQL
  • Oracle
  • PostgreQueryCsv
  • PostgreSQLText
  • RFC4180
  • TDF

Tôi đã sử dụng CSV Commons hộp cát khá lâu và chưa bao giờ gặp sự cố. Tôi thực sự hy vọng họ thúc đẩy nó hoàn toàn đứng vững và đưa nó ra khỏi hộp cát.
Alex Marshall

3
@ bmatthews68 liên kết hộp cát không còn tồn tại - có vẻ như nó đã được chuyển sang apache commons thích hợp (tôi cũng chỉnh sửa liên kết trong câu trả lời)
drevicko

Ví dụ về Apache Commons tại đây: apisonar.com/java-examples/org.apache.commons.csv.html
APISonar

83

Tôi đã sử dụng OpenCSV trong quá khứ.

import au.com.bytecode.opencsv.CSVReader;

Chuỗi fileName = "data.csv";
Trình đọc CSVReader = CSVReader mới (FileReader mới (tên tệp));

// nếu dòng đầu tiên là tiêu đề Chuỗi [] header = reader.readNext ();
// lặp qua reader.readNext cho đến khi nó trả về null Chuỗi [] line = reader.readNext ();

Có một số lựa chọn khác trong câu trả lời cho câu hỏi khác .


Thật không may, bản tải xuống mới nhất của OpenCSV (v2.2 tại thời điểm nhận xét) không biên dịch và chúng không cung cấp tệp nhị phân dựng sẵn.
opyate

9
Gói tôi tải xuống từ SourceForge có tệp nhị phân trong thư mục triển khai.
Mike Sickler

8
Nếu bạn đang sử dụng maven, xin lưu ý rằng mã phụ thuộc trên trang web chính thức có khai báo phiên bản "2.0" có một số lỗi, nhưng có phiên bản 2.3 được cập nhật trong kho.
broundee

lib này không ghi tập tin trong chủ đề riêng biệt, không?
Ewoks

3
theo github.com/uniVocity/csv-parsers-comparison trung bình chậm hơn 73% so với uniVocity ..
Ewoks

32

Cập nhật: Mã trong câu trả lời này là dành cho Super CSV 1.52. Có thể tìm thấy các ví dụ mã cập nhật cho Super CSV 2.4.0 tại trang web của dự án: http://super-csv.github.io/super-csv/index.html


Dự án SuperCSV trực tiếp hỗ trợ phân tích cú pháp và thao tác cấu trúc của các ô CSV. Từ http://super-csv.github.io/super-csv/examples_reading.html bạn sẽ tìm thấy, vd

cho một lớp học

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; }
}

và bạn có tệp CSV có tiêu đề. Hãy giả sử nội dung sau đây

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

Sau đó, bạn có thể tạo một phiên bản của UserBean và điền vào nó các giá trị từ dòng thứ hai của tệp với mã sau đây

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();
    }
  }
}

sử dụng "đặc tả thao tác" sau đây

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
Mã của bạn sẽ không biên dịch nên tôi đã gửi một số chỉnh sửa. Ngoài ra, ParseDate () không hoạt động chính xác nên tôi đã thay thế nó để đọc Chuỗi. Nó có thể được phân tích cú pháp sau.

1
Hạn chế lớn: SuperCSV không phải là chủ đề an toàn, tôi sẽ tìm đến Jackson, mặc dù nó có thể bị giới hạn nhiều tính năng hơn
ZiglioUK

SuperCsv cũng không cho phép sử dụng multimaps. Sẽ thật tuyệt khi thấy nó hoạt động với MultiMaps.
Sid

19

Đọc mô tả định dạng CSV khiến tôi cảm thấy rằng việc sử dụng thư viện của bên thứ 3 sẽ bớt đau đầu hơn là tự viết:

Wikipedia liệt kê 10 hoặc một số thư viện được biết đến:

Tôi so sánh libs được liệt kê bằng cách sử dụng một số loại danh sách kiểm tra. OpenCSV hóa ra một người chiến thắng với tôi (YMMV) với kết quả như sau:

+ 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

Chúng tôi sử dụng JavaCSV , nó hoạt động khá tốt


3
Vấn đề duy nhất với thư viện này là nó sẽ không cho phép bạn xuất các tệp CSV bằng các đầu cuối dòng Windows ( \r\n) khi không chạy trên Windows. Tác giả đã không cung cấp hỗ trợ trong nhiều năm. Tôi đã phải rẽ nhánh nó để cho phép tính năng còn thiếu đó: JavaCSV 2.2
Mosty Mostacho

6

Đối với ứng dụng doanh nghiệp cuối cùng tôi đã làm việc cần xử lý một lượng CSV đáng chú ý - một vài tháng trước - tôi đã sử dụng SuperCSV tại sourceforge và thấy nó đơn giản, mạnh mẽ và không có vấn đề.


+1 cho SuperCSV, nhưng nó có một số lỗi khó chịu chưa được sửa, các lỗi mới hiện chưa được xử lý và bản phát hành cuối cùng đã gần hai năm. Nhưng chúng tôi đang sử dụng một phiên bản vá / sửa đổi trong sản xuất mà không có bất kỳ vấn đề.
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1 gần đây đã được phát hành. Nó bao gồm nhiều sửa lỗi và các tính năng mới (bao gồm hỗ trợ Maven và tiện ích mở rộng Dozer mới để ánh xạ các thuộc tính và mảng / Bộ sưu tập lồng nhau)
James Bassett

1
@ Hound-Dog Cảm ơn bạn đã cập nhật, tôi đã nhận thấy bản beta mới và tôi rất vui khi thấy dự án còn sống - mặc dù tần suất cam kết vẫn khiến tôi lo lắng một chút (hầu như tất cả chỉ cam kết trong vài ngày). Nhưng tôi sẽ xem xét. Có một ngày phát hành ước tính của 2.0 cuối cùng?
MRalwasser

2
@MRalwasser Tôi là nhà phát triển duy nhất tại thời điểm này và có công việc toàn thời gian, vì vậy tôi có xu hướng làm việc này bất cứ khi nào tôi có một ngày cuối tuần miễn phí - do đó, cam kết lẻ tẻ :) Gần 1000 lượt tải xuống bản beta hiện tại và không có lỗi, Vì vậy, tìm kiếm theo dõi cho một bản phát hành cuối cùng vào đầu tháng tới. Nếu bạn có bất kỳ ý tưởng cho các tính năng trong tương lai xin vui lòng cho chúng tôi biết.
James Bassett

1
SuperCSV không phải là chủ đề an toàn trong giai đoạn này, điều đó làm cho nó không thực sự mạnh mẽ
ZiglioUK

5

Bạn có thể sử dụng csvreader api & tải xuống từ vị trí sau:

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

hoặc là

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

Sử dụng mã sau đây:

/ ************ 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();
        }

    }

}

Viết / Nối vào tệp CSV

Mã số:

/************* 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

Định dạng CSV nghe có vẻ dễ dàng đối với StringTokenizer nhưng nó có thể trở nên phức tạp hơn. Ở Đức, một dấu chấm phẩy được sử dụng như một dấu phân cách và các ô chứa dấu phân cách cần phải được thoát. Bạn sẽ không dễ dàng xử lý điều đó với StringTokenizer.

Tôi sẽ truy cập http://sourceforge.net/projects/javacsv


0

Nếu bạn có ý định đọc csv từ excel, thì có một số trường hợp góc thú vị. Tôi không thể nhớ tất cả, nhưng apache commons không có khả năng xử lý chính xác (ví dụ như các url).

Hãy chắc chắn kiểm tra đầu ra excel với dấu ngoặc kép và dấu phẩy và dấu gạch chéo ở mọi nơi.


Thư viện CSV của Commons cung cấp một biến thể cụ thể cho Microsoft Excel . Tôi không biết nếu bây giờ xử lý các vấn đề bạn đề cập hay không.
Basil Bourque
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.