CSV API สำหรับ Java [ปิด]


164

ทุกคนสามารถแนะนำ API ง่าย ๆ ที่จะอนุญาตให้ฉันใช้อ่านไฟล์อินพุต CSV ทำการแปลงแบบง่าย ๆ แล้วเขียนมัน

google อย่างรวดเร็วพบhttp://flatpack.sourceforge.net/ซึ่งดูมีแนวโน้ม

ฉันแค่ต้องการตรวจสอบสิ่งที่คนอื่นใช้ก่อนที่ฉันจะจับคู่กับ API นี้


ใช้คำแนะนำซอฟต์แวร์ของไซต์น้องแลกเปลี่ยนการแลกเปลี่ยนเมื่อขอคำแนะนำเกี่ยวกับไลบรารีซอฟต์แวร์ มีเพลงฮิตหลาย Java และ CSV
Basil Bourque

คำตอบ:


32

Apache Commons CSV

ตรวจสอบApache CSV

ห้องสมุดนี้อ่านและเขียนหลายรูปแบบของ CSVรวมทั้งมาตรฐานRFC 4180 อ่าน / เขียนไฟล์ที่คั่นด้วย Tab ด้วย

  • สันทัด
  • InformixUnload
  • InformixUnloadCsv
  • MySQL
  • คำพยากรณ์
  • PostgreSQLCsv
  • PostgreSQLText
  • RFC4180
  • TDF

ฉันใช้ Sandboxed CSV Commons มาระยะหนึ่งแล้วและไม่เคยประสบปัญหา ฉันหวังว่าพวกเขาจะส่งเสริมให้มันยืนอย่างเต็มที่และนำมันออกมาจากกล่องทราย
Alex Marshall

3
@ bmatthews68 ลิงค์ Sandbox เป็นตาย - ดูเหมือนว่ามันย้ายไปอยู่ที่คอมมอนส์ Apache ที่เหมาะสม (ฉันแก้ไขการเชื่อมโยงในคำตอบเกินไป)
drevicko

Apache Commons ตัวอย่างที่นี่: apisonar.com/java-examples/org.apache.commons.csv.html
APISonar

83

ฉันเคยใช้OpenCSVมาก่อน

import au.com.bytecode.opencsv.CSVReader;

String fileName = "data.csv";
CSVReader reader = new CSVReader (ใหม่ FileReader (ชื่อไฟล์));

// ถ้าบรรทัดแรกคือส่วนหัว String [] header = reader.readNext ();
// วนซ้ำกว่า reader.readNext จนกว่าจะส่งคืน null String [] line = reader.readNext ();

มีบางตัวเลือกอื่น ๆ ในคำตอบที่กำลังจะคำถามอื่น


น่าเสียดายที่การดาวน์โหลดล่าสุดของ OpenCSV (v2.2 ณ เวลาที่แสดงความคิดเห็น) ไม่ได้รวบรวมและไม่ได้จัดเตรียมไบนารีที่สร้างไว้ล่วงหน้า
opyate

9
แพ็คเกจที่ฉันดาวน์โหลดจาก SourceForge มีเลขฐานสองในโฟลเดอร์ปรับใช้
Mike Sickler

8
หากคุณใช้ Maven โปรดทราบว่ารหัสอ้างอิงในเว็บไซต์อย่างเป็นทางการมีการประกาศรุ่น "2.0" ซึ่งมีข้อบกพร่องบางอย่าง แต่มีการอัปเดตเวอร์ชั่น 2.3 ในที่เก็บ
broundee

lib นี้ไม่ได้เขียนไฟล์ในเธรดแยกต่างหากใช่ไหม
Ewoks

3
ตามgithub.com/uniVocity/csv-parsers-comparisonโดยเฉลี่ย 73% ช้ากว่า uniVocity ..
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 ไม่ใช่หัวข้อที่ปลอดภัยฉันจะไปหาแจ็คสันถึงแม้ว่ามันอาจจะมีฟีเจอร์ จำกัด มากขึ้น
ZiglioUK

SuperCsv ยังไม่อนุญาตให้ใช้ Multimaps ยินดีที่ได้เห็นมันใช้งานได้กับหลายแผนที่
ซิด

19

การอ่านคำอธิบายรูปแบบ CSV ทำให้ฉันรู้สึกว่าการใช้ห้องสมุดบุคคลที่สามจะปวดหัวน้อยกว่าการเขียนเอง:

Wikipedia แสดงรายการ 10 หรือสิ่งที่ห้องสมุดรู้จัก:

ฉันเปรียบเทียบ libs ที่ระบุโดยใช้รายการตรวจสอบบางประเภท 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
ปัญหาเดียวของไลบรารี่นี้คือมันจะไม่อนุญาตให้คุณส่งออกไฟล์ CSV ด้วยตัวยุติบรรทัด Windows ( \r\n) เมื่อไม่ได้ทำงานบน Windows ผู้เขียนไม่ได้ให้การสนับสนุนเป็นเวลาหลายปี ฉันต้องแยกมันเพื่อให้คุณสมบัติที่ขาดหายไป: JavaCSV 2.2
Mosty Mostacho

6

สำหรับแอปพลิเคชั่นระดับองค์กรครั้งสุดท้ายฉันทำงานเกี่ยวกับสิ่งที่จำเป็นในการจัดการ CSV จำนวนหนึ่ง - สองสามเดือนที่ผ่านมา - ฉันใช้SuperCSVที่ sourceforge และพบว่าเรียบง่ายแข็งแกร่งและปราศจากปัญหา


+1 สำหรับ SuperCSV แต่มีข้อบกพร่องที่น่ารังเกียจซึ่งยังไม่ได้แก้ไขข้อบกพร่องใหม่ยังไม่ได้รับการจัดการในปัจจุบันและการเผยแพร่ครั้งล่าสุดเกือบสองปี แต่เรากำลังใช้เวอร์ชันที่ได้รับการติดตั้งหรือแก้ไขในการผลิตโดยไม่มีปัญหาใด ๆ
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1เพิ่งเปิดตัว มันมีการแก้ไขข้อบกพร่องมากมายและคุณสมบัติใหม่ (รวมถึงการสนับสนุน Maven และส่วนขยาย Dozer ใหม่สำหรับการแมปคุณสมบัติที่ซ้อนกันและอาร์เรย์ / คอลเลกชัน)
James Bassett

1
@ Hound-Dog ขอบคุณสำหรับการอัปเดตฉันสังเกตเห็นเบต้าใหม่แล้วและฉันดีใจที่ได้เห็นโปรเจกต์มีชีวิตชีวา - แม้ว่าความถี่ของการคอมมิทยังคงทำให้ฉันกลัวฉันเล็กน้อย (เกือบทุกคอมมิทในสองสามวันเท่านั้น) แต่ฉันจะดู มีวันวางจำหน่ายโดยประมาณของ 2.0 รุ่นสุดท้ายหรือไม่?
MRalwasser

2
@Malwasser ฉันเป็น dev คนเดียวในขณะนี้และทำงานเต็มเวลาดังนั้นฉันจึงมักจะทำงานนี้เมื่อใดก็ตามที่ฉันได้รับวันหยุดสุดสัปดาห์ฟรี - ดังนั้นจึงเป็นครั้งคราว commits :) เกือบ 1,000 ดาวน์โหลด 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

หากคุณตั้งใจจะอ่าน csv จาก excel มีบางกรณีที่น่าสนใจ ฉันจำไม่ได้ทั้งหมด แต่ apache คอมมอนส์ csv ไม่สามารถจัดการได้อย่างถูกต้อง (ตัวอย่างเช่น URL)

อย่าลืมทดสอบเอาต์พุต Excel ด้วยเครื่องหมายคำพูดและเครื่องหมายจุลภาคและเครื่องหมายสแลชทั่วสถานที่


Apache Commons CSVห้องสมุดจะมีตัวแปรที่เฉพาะเจาะจงสำหรับ Microsoft Excel ฉันไม่รู้ว่าตอนนี้จัดการกับปัญหาที่คุณพูดถึงหรือไม่
Basil Bourque
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.