Java için CSV API [kapalı]


164

Herkes bir CSV giriş dosyasını okumak, bazı basit dönüşümler yapmak ve daha sonra yazmak kullanmama izin verecek basit bir API önerebilir miyim.

Hızlı bir google, umut verici görünen http://flatpack.sourceforge.net/ adresini buldu .

Kendimi bu API ile eşleştirmeden önce başkalarının ne kullandığını kontrol etmek istedim.


Bir yazılım kütüphanesinde öneri isterken kardeş site Yazılım Önerileri Stack Exchange'i kullanın . Java ve CSV için birkaç isabete sahiptir .
Basil Bourque

Yanıtlar:


32

Apache Commons CSV

Apache Common CSV'ye göz atın .

Bu kütüphane , standart RFC 4180 de dahil olmak üzere çeşitli CSV varyasyonlarını okur ve yazar . Sekmeyle ayrılmış dosyaları da okur / yazar .

  • Excel
  • InformixUnload
  • InformixUnloadCsv
  • MySQL
  • torpil
  • PostgreSQLCsv
  • PostgreSQLText
  • RFC4180
  • TDF

Korumalı alandaki Commons CSV'yi oldukça uzun süredir kullandım ve hiçbir zaman sorun yaşamadım. Umarım tam ayakta durmasını ve kum havuzundan çıkarmasını umarlar.
Alex Marshall

3
@ bmatthews68 sandbox bağlantısı geçersiz - apache commons'a doğru taşınmış gibi görünüyor (cevabın linkini de düzenledim)
drevicko


83

Geçmişte OpenCSV kullandım .

import au.com.bytecode.opencsv.CSVReader;

String fileName = "data.csv";
CSVReader okuyucu = yeni CSVReader (yeni FileReader (dosyaAdı));

// ilk satır başlıksa String [] header = reader.readNext ();
// null değerine dönene kadar reader.readNext üzerinden yineleme String [] line = reader.readNext ();

Başka bir sorunun cevabında başka seçenekler de vardı .


Ne yazık ki, OpenCSV'nin en son indirmesi (yorum sırasında v2.2) derlenmemiştir ve önceden oluşturulmuş bir ikili dosya sağlamaz.
Mart'ta

9
SourceForge'dan indirdiğim paketin dağıtım klasöründe bir ikili dosya vardı.
Mike Sickler

8
Maven kullanıyorsanız, resmi web sitesindeki bağımlılık kodunun bazı hatalara sahip sürüm 2.0 "2.0" içerdiğini, ancak depolarda güncellenmiş 2.3 sürümü olduğunu lütfen unutmayın.
broundee

bu lib ayrı bir iş parçacığında dosya yazmıyor, değil mi?
Ewoks

3
github.com/uniVocity/csv-parsers-comparison göre uniVocity ortalama% 73 daha yavaş ..
Ewoks

32

Güncelleme: Bu yanıttaki kod Super CSV 1.52 içindir. Super CSV 2.4.0 için güncellenmiş kod örnekleri proje web sitesinde bulunabilir: http://super-csv.github.io/super-csv/index.html


SuperCSV projesi, CSV hücrelerinin ayrıştırılmasını ve yapılandırılmış manipülasyonunu doğrudan destekler. Gönderen http://super-csv.github.io/super-csv/examples_reading.html bulacaksınız örn

bir sınıf verildi

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

ve başlıklı bir CSV dosyanız var. Aşağıdaki içeriği varsayalım

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

Daha sonra UserBean'ın bir örneğini oluşturabilir ve bunu dosyanın ikinci satırındaki değerlerle aşağıdaki kodla doldurabilirsiniz

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

aşağıdaki "manipülasyon spesifikasyonunu" kullanarak

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
Kodunuz derlenmediği için bazı düzeltmeler gönderdim. Ayrıca, ParseDate () düzgün çalışmıyor, bu yüzden bir String okumak için değiştirdim. Daha sonra ayrıştırılabilir.

1
Büyük sınırlama: SuperCSV threadsafe değildir, daha sınırlı özelliklere sahip olsa da Jackson'a
bakacağım

SuperCsv ayrıca çoklu haritaların kullanımına izin vermez. MultiMaps ile çalıştığını görmek güzel olurdu.
Sid

19

CSV biçimi açıklamasını okumak, üçüncü taraf kitaplığını kullanmanın kendim yazmaktan daha az baş ağrısı olacağını hissettiriyor:

Wikipedia 10 veya bilinen bir kütüphaneyi listeler:

Bir tür kontrol listesi kullanarak listelenen kütüphaneleri karşılaştırdım. OpenCSV bana bir sonuç verdi (YMMV) şu sonuçları verdi:

+ 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

Biz kullanmak JavaCSV , oldukça iyi çalışıyor


3
Bu kitaplıkla ilgili tek sorun \r\n, Windows'ta çalışmadığında CSV dosyalarını Windows satır sonlandırıcılarıyla ( ) çıkarmanıza izin vermemesidir . Yazar yıllarca destek vermedi. Bu eksik özelliğe izin vermek için çatallamak zorunda kaldım: JavaCSV 2.2
Mosty Mostacho

6

Son kurumsal uygulama için, birkaç ay önce önemli miktarda CSV'yi ele almak için gerekli olan üzerinde çalıştım , sourceforge'da SuperCSV'yi kullandım ve basit, sağlam ve sorunsuz buldum.


SuperCSV için +1, ancak henüz düzeltilmemiş bazı kötü hatalar var, yeni hatalar şu anda ele alınmıyor ve son sürüm neredeyse iki yaşında. Ancak üretimde yamalı / değiştirilmiş bir versiyonu sorunsuz olarak kullanıyoruz.
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1 son zamanlarda piyasaya çıktı. Birçok hata düzeltmesi ve yeni özellik içerir (Maven desteği ve iç içe geçmiş özellikleri ve dizileri / Koleksiyonları eşlemek için yeni bir Dozer uzantısı dahil)
James Bassett

1
@ Hound-Dog Güncelleme için teşekkür ederim, yeni beta'yı zaten fark ettim ve projeyi canlı olarak gördüğüme sevindim - taahhütlerin sıklığı hala beni biraz korkutuyor (neredeyse sadece birkaç günde tamamlanıyor). Ama bir bakayım. Nihai 2.0'ın tahmini çıkış tarihi var mı?
MRalwasser

2
@MRalwasser Şu anda tek geliştiriciyim ve tam zamanlı çalışıyorum, bu yüzden ücretsiz bir hafta sonu aldığımda bunun üzerinde çalışma eğilimindeyim - dolayısıyla ara sıra devreye giriyor :) Şu anda betanın yaklaşık 1000 SF indirme ve hata yok, bu yüzden gelecek ayın başlarında nihai bir sürümün izini sürecek. Gelecekteki özellikler için herhangi bir fikriniz varsa lütfen bize bildirin.
James Bassett

1
SuperCSV bu aşamada gerçekten güvenli değildir, bu da gerçekten sağlam değildir.
ZiglioUK

5

Csvreader api'yi kullanabilir ve aşağıdaki konumdan indirebilirsiniz:

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

veya

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

Aşağıdaki kodu kullanın:

/ ************ 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 dosyasına Yazma / Ekleme

Kod:

/************* 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 formatı StringTokenizer için yeterince kolay geliyor, ancak daha karmaşık hale gelebilir. Burada Almanya'da bir noktalı virgül, sınırlayıcı olarak kullanılır ve sınırlayıcı içeren hücrelerin kaçması gerekir. StringTokenizer ile bunu kolayca halledemeyeceksiniz.

Ben gitmek istiyorum http://sourceforge.net/projects/javacsv


0

Excel'den csv okumak istiyorsanız, o zaman bazı ilginç köşe vakaları vardır. Hepsini hatırlayamıyorum, ama apache commons csv doğru şekilde işleyemedi (örneğin, url'ler ile).

Excel çıktısını tırnak işaretleri ve virgül ve eğik çizgilerle test ettiğinizden emin olun.


Apache Commons CSV kütüphane sunuyor Microsoft Excel için belirli bir varyasyonu . Bunun şimdi bahsettiğiniz sorunları ele alıp almadığını bilmiyorum.
Basil Bourque
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.