API CSV untuk Java [ditutup]


164

Adakah yang bisa merekomendasikan API sederhana yang akan memungkinkan saya untuk menggunakan membaca file input CSV, melakukan beberapa transformasi sederhana, dan kemudian menulisnya.

Google cepat telah menemukan http://flatpack.sourceforge.net/ yang terlihat menjanjikan.

Saya hanya ingin memeriksa apa yang digunakan orang lain sebelum saya memasangkan diri ke API ini.


Gunakan situs saudara Rekomendasi Stack Exchange ketika meminta saran tentang perpustakaan perangkat lunak. Memiliki beberapa hit untuk Java & CSV .
Basil Bourque

Jawaban:


32

Apache Commons CSV

Lihat Apache Common CSV .

Perpustakaan ini membaca dan menulis beberapa variasi CSV , termasuk yang standar RFC 4180 . Juga membaca / menulis file yang dibatasi Tab .

  • Unggul
  • InformixUnload
  • InformixUnloadCsv
  • MySQL
  • Peramal
  • PostgreSQLCsv
  • PostgreSQLText
  • RFC4180
  • TDF

Saya telah menggunakan sandboxed Commons CSV untuk beberapa waktu dan tidak pernah mengalami masalah. Saya benar-benar berharap mereka mempromosikannya dengan berdiri penuh dan mengeluarkannya dari kotak pasir.
Alex Marshall

3
@ bmatthews68 tautan sandbox tidak berfungsi - sepertinya dipindahkan ke apache commons proper (saya mengedit tautan dalam jawabannya juga)
drevicko

Contoh-contoh Apache Commons di sini: apisonar.com/java-examples/org.apache.commons.csv.html
APISonar

83

Saya telah menggunakan OpenCSV di masa lalu.

import au.com.bytecode.opencsv.CSVReader;

String fileName = "data.csv";
CSVReader reader = CSVReader baru (FileReader baru (fileName));

// jika baris pertama adalah tajuk String [] header = reader.readNext ();
// iterate over reader.readNext hingga kembali nol String [] line = reader.readNext ();

Ada beberapa pilihan lain dalam jawaban untuk pertanyaan lain .


Sayangnya, unduhan terbaru OpenCSV (v2.2 pada saat komentar) tidak dapat dikompilasi, dan mereka tidak menyediakan biner pra-bangun.
opyate

9
Paket yang saya unduh dari SourceForge memiliki biner di folder deploy.
Mike Sickler

8
Jika Anda menggunakan pakar, harap perhatikan bahwa kode dependensi di situs web resmi berisi deklarasi versi "2.0" yang memiliki beberapa bug, tetapi ada pembaruan versi 2.3 dalam repositori.
broundee

Lib ini tidak menulis file di utas terpisah, bukan?
Ewoks

3
menurut github.com/uniVocity/csv-parsers-comparison rata-rata 73% lebih lambat dari uniVocity ..
Ewoks

32

Pembaruan: Kode dalam jawaban ini adalah untuk Super CSV 1.52. Contoh kode yang diperbarui untuk Super CSV 2.4.0 dapat ditemukan di situs web proyek: http://super-csv.github.io/super-csv/index.html


Proyek SuperCSV secara langsung mendukung parsing dan manipulasi terstruktur sel CSV. Dari http://super-csv.github.io/super-csv/examples_reading.html Anda akan menemukan misalnya

diberi kelas

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

dan bahwa Anda memiliki file CSV dengan header. Mari kita asumsikan konten berikut

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

Anda kemudian dapat membuat instance dari UserBean dan mengisinya dengan nilai-nilai dari baris kedua file dengan kode berikut

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

menggunakan "spesifikasi manipulasi" berikut ini

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
Kode Anda tidak dapat dikompilasi jadi saya mengirimkan beberapa koreksi. Juga, ParseDate () tidak berfungsi dengan benar jadi saya menggantinya untuk membaca String. Itu bisa diuraikan nanti.

1
Batasan besar: SuperCSV bukan threadsafe, saya akan mencari ke Jackson, meskipun mungkin fitur lebih terbatas
ZiglioUK

SuperCsv juga tidak mengizinkan penggunaan multimaps. Akan menyenangkan melihatnya berfungsi dengan MultiMaps.
Sid

19

Membaca deskripsi format CSV membuat saya merasa bahwa menggunakan perpustakaan pihak ke-3 akan lebih sedikit sakit kepala daripada menulisnya sendiri:

Wikipedia mencantumkan 10 atau sesuatu perpustakaan yang dikenal:

Saya membandingkan lib yang terdaftar menggunakan semacam daftar periksa. OpenCSV menghasilkan pemenang untuk saya (YMMV) dengan hasil sebagai berikut:

+ 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

Kami menggunakan JavaCSV , itu bekerja dengan cukup baik


3
Satu-satunya masalah dengan perpustakaan ini adalah bahwa ia tidak memungkinkan Anda untuk menghasilkan file CSV dengan terminator jalur Windows ( \r\n) ketika tidak berjalan di Windows. Penulis tidak memberikan dukungan selama bertahun-tahun. Saya harus memotongnya
Mosty Mostacho

6

Untuk aplikasi perusahaan yang terakhir saya kerjakan yang perlu menangani sejumlah CSV - beberapa bulan yang lalu - saya menggunakan SuperCSV di sourceforge dan merasa sederhana, kuat, dan bebas masalah.


+1 untuk SuperCSV, tetapi memiliki beberapa bug jahat yang belum diperbaiki, bug baru tidak ditangani saat ini, dan rilis terakhir sudah hampir dua tahun. Tetapi kami menggunakan versi tambalan / modifikasi dalam produksi tanpa masalah.
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1 baru-baru ini telah dirilis. Ini mencakup banyak perbaikan bug dan fitur baru (termasuk dukungan Maven dan ekstensi Dozer baru untuk memetakan properti dan array / Koleksi bersarang)
James Bassett

1
@ Hound-Dog Terima kasih atas pembaruannya, saya sudah melihat beta baru dan saya senang melihat proyek ini hidup - walaupun frekuensi komit masih membuat saya sedikit takut (hampir semua hanya berkomitmen pada beberapa hari saja). Tapi saya akan memeriksanya. Apakah ada perkiraan tanggal rilis final 2.0?
MRalwasser

2
@MRalwasser Saya satu-satunya pengembang saat ini dan memiliki pekerjaan penuh waktu, jadi saya cenderung mengerjakan ini setiap kali saya mendapatkan akhir pekan gratis - karenanya sporadis berkomitmen :) Hampir 1000 unduhan SF versi beta sekarang, dan tidak ada bug, jadi mencari di jalur untuk rilis final awal bulan depan. Jika Anda memiliki ide untuk fitur masa depan, silakan beri tahu kami.
James Bassett

1
SuperCSV bukan threadsafe pada tahap ini, yang membuatnya tidak benar-benar kuat
ZiglioUK

5

Anda dapat menggunakan api csvreader & mengunduh dari lokasi berikut:

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

atau

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

Gunakan kode berikut:

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

    }

}

Tulis / Tambahkan ke file CSV

Kode:

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

Format CSV terdengar cukup mudah untuk StringTokenizer tetapi bisa menjadi lebih rumit. Di sini, di Jerman, tanda titik koma digunakan sebagai pembatas dan sel-sel yang mengandung pembatas harus diloloskan. Anda tidak akan menangani itu dengan mudah dengan StringTokenizer.

Saya akan mencari http://sourceforge.net/projects/javacsv


0

Jika Anda berniat untuk membaca csv dari excel, maka ada beberapa kasus sudut yang menarik. Saya tidak dapat mengingat semuanya, tetapi apache commons csv tidak dapat menanganinya dengan benar (misalnya, url).

Pastikan untuk menguji output excel dengan tanda kutip dan koma dan garis miring di semua tempat.


The Apache Commons CSV perpustakaan memang menawarkan varian khusus untuk Microsoft Excel . Saya tidak tahu apakah itu sekarang menangani masalah yang Anda sebutkan atau tidak.
Basil Bourque
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.