您的位置:首页 > 编程语言 > Java开发

JAVA学习提高之----JAVA开源项目之操作csv文件

2008-12-22 14:51 507 查看
JAVA操作csv文件的开源项目很多,如想查可看下面链接
http://sourceforge.net/search/?type_of_search=soft&words=csv

看到网上有人认为不错的一个,地址是:
http://opencsv.sourceforge.net/

下载源码地址:http://sourceforge.net/project/showfiles.php?group_id=148905&package_id=164539
最新的是1.8版的,因为最近项目要用到CSV文件的读写,所以对有关内容进行学习,主要是对CSV文件分析器类的学习,下面只是发布出来的API,具体的类下载的资源里面有。

具体思路:因为csv file本身可以当作文件文件来操作,所以只需使用BufferedReader的readLine方法即可读取一行了。

opencsv

An Open Source Java csv library under commercial-friendly license... committed to changing the world, one comma at a time...

What is opencsv?

opencsv is a very simple csv (comma-separated values) parser library for Java. It was developed because all of current csv parsers I've come across don't have commercial-friendly licenses.

Where can I get it?

Source and binaries are available from Sourceforge.

What features does opencsv support?

opencsv supports all the basic csv-type things you're likely to want to do:

* Arbitrary numbers of values per line

* Ignoring commas in quoted elements

* Handling quoted entries with embedded carriage returns (ie entries that span multiple lines)

* Configurable separator and quote characters (or use sensible defaults)

* Read all the entries at once, or use an Iterator style model

* Creating csv files from String[] (ie. automatic escaping of embedded quote chars)

How do I read and parse a CSV file?

If you want to use an Iterator style pattern, you might do something like this:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));

String [] nextLine;

while ((nextLine = reader.readNext()) != null) {

// nextLine[] is an array of values from the line

System.out.println(nextLine[0] + nextLine[1] + "etc...");

}

Or, if you might just want to slurp the whole lot into a List, just call readAll()...

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));

List myEntries = reader.readAll();

which will give you a List of String[] that you can iterate over. If all else fails, check out the Javadoc.

Can I use my own separators and quote characters?

Yes. There are constructors that cater for supplying your own separator and quote characters. Say you're using a tab for your separator, you can do something like this:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '/t');

And if you single quoted your escaped characters rather than double quote them, you can use the three arg constructor:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '/t', '/'');

You may also skip the first few lines of the file if you know that the content doesn't start till later in the file. So, for example, you can skip the first two lines by doing:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '/t', '/'', 2);

Can I write csv files with opencsv?

Yes. There is a CSVWriter in the same package that follows the same semantics as the CSVReader. For example, to write a tab separated file:

CSVWriter writer = new CSVWriter(new FileWriter("yourfile.csv"), '/t');

// feed in your array (or convert your data to an array)

String[] entries = "first#second#third".split("#");

writer.writeNext(entries);

writer.close();

If you'd prefer to use your own quote characters, you may use the three arg version of the constructor, which takes a quote character (or feel free to pass in CSVWriter.NO_QUOTE_CHARACTER).

You can also customise the line terminators used in the generated file (which is handy when you're exporting from your Linux web application to Windows clients). There is a constructor argument for this purpose.

Can I dump out SQL tables to CSV?

Yes you can. Sean Sullivan added a neat feature to CSVWriter so you can pass writeAll() a ResultSet.

java.sql.ResultSet myResultSet = ....

writer.writeAll(myResultSet, includeHeaders);

Is there a way to bind my CSV file to a list of Javabeans?

Yes there is. Kyle Miller added a new set of classes to allow you to bind a CSV file to a list of JavaBeans based on column name, column position, or a custom mapping strategy. You can find the new classes in the au.com.bytecode.opencsv.bean package. Here's how you can map to a java bean based on the field positions in your CSV file:

ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();

strat.setType(YourOrderBean.class);

String[] columns = new String[] {"name", "orderNumber", "id"}; // the fields to bind do in your JavaBean

strat.setColumnMapping(columns);

CsvToBean csv = new CsvToBean();

List list = csv.parse(strat, yourReader);

For more detailed examples, check out the test cases for each of the available mapping strategies under the /test/au/com/bytecode/opencsv/bean/.

Can I use opencsv in my commercial applications?

Yes. opencsv is available under a commercial-friendly Apache 2.0 license. You are free to include it in your commericial applications without any fee or charge, and you are free to modify it to suit your circumstances. To find out more details of the license, read the Apache 2.0 license agreement.

Can I get the source? More example code?

Yes. The download from the SourceForge page includes the full source in the /src directory. It's one file, so go crazy. There is also a sample addressbook csv reader in the /examples directory. And for extra marks, there's a JUnit test suite in the /test directory.

Who maintains opencsv?

opencsv was developed in a couple of hours by Glen Smith. You can read his blog for more info and contact details.

If you've found a bug, you can report it on the project page at Sourceforge. Please post a sample file that demonstrates your issue. For bonus marks, post a patch too. :-)

对应的方法为:

package au.com.bytecode.opencsv;

/**

Copyright 2005 Bytecode Pty Ltd.

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

*/

import java.io.BufferedReader;

import java.io.IOException;

import java.io.Reader;

import java.util.ArrayList;

import java.util.List;

/**

* A very simple CSV reader released under a commercial-friendly license.

*

* @author Glen Smith

*

*/

public class CSVReader {

private BufferedReader br;

private boolean hasNext = true;

private char separator;

private char quotechar;

private int skipLines;

private boolean linesSkiped;

/** The default separator to use if none is supplied to the constructor. */

public static final char DEFAULT_SEPARATOR = ',';

/**

* The default quote character to use if none is supplied to the

* constructor.

*/

public static final char DEFAULT_QUOTE_CHARACTER = '"';

/**

* The default line to start reading.

*/

public static final int DEFAULT_SKIP_LINES = 0;

/**

* Constructs CSVReader using a comma for the separator.

*

* @param reader

* the reader to an underlying CSV source.

*/

public CSVReader(Reader reader) {

this(reader, DEFAULT_SEPARATOR);

}

/**

* Constructs CSVReader with supplied separator.

*

* @param reader

* the reader to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries.

*/

public CSVReader(Reader reader, char separator) {

this(reader, separator, DEFAULT_QUOTE_CHARACTER);

}

/**

* Constructs CSVReader with supplied separator and quote char.

*

* @param reader

* the reader to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

*/

public CSVReader(Reader reader, char separator, char quotechar) {

this(reader, separator, quotechar, DEFAULT_SKIP_LINES);

}

/**

* Constructs CSVReader with supplied separator and quote char.

*

* @param reader

* the reader to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

* @param line

* the line number to skip for start reading

*/

public CSVReader(Reader reader, char separator, char quotechar, int line) {

this.br = new BufferedReader(reader);

this.separator = separator;

this.quotechar = quotechar;

this.skipLines = line;

}

/**

* Reads the entire file into a List with each element being a String[] of

* tokens.

*

* @return a List of String[], with each String[] representing a line of the

* file.

*

* @throws IOException

* if bad things happen during the read

*/

public List readAll() throws IOException {

List allElements = new ArrayList();

while (hasNext) {

String[] nextLineAsTokens = readNext();

if (nextLineAsTokens != null)

allElements.add(nextLineAsTokens);

}

return allElements;

}

/**

* Reads the next line from the buffer and converts to a string array.

*

* @return a string array with each comma-separated element as a separate

* entry.

*

* @throws IOException

* if bad things happen during the read

*/

public String[] readNext() throws IOException {

String nextLine = getNextLine();

return hasNext ? parseLine(nextLine) : null;

}

/**

* Reads the next line from the file.

*

* @return the next line from the file without trailing newline

* @throws IOException

* if bad things happen during the read

*/

private String getNextLine() throws IOException {

if (!this.linesSkiped) {

for (int i = 0; i < skipLines; i++) {

br.readLine();

}

this.linesSkiped = true;

}

String nextLine = br.readLine();

if (nextLine == null) {

hasNext = false;

}

return hasNext ? nextLine : null;

}

/**

* Parses an incoming String and returns an array of elements.

*

* @param nextLine

* the string to parse

* @return the comma-tokenized list of elements, or null if nextLine is null

* @throws IOException if bad things happen during the read

*/

private String[] parseLine(String nextLine) throws IOException {

if (nextLine == null) {

return null;

}

List tokensOnThisLine = new ArrayList();

StringBuffer sb = new StringBuffer();

boolean inQuotes = false;

do {

if (inQuotes) {

// continuing a quoted section, reappend newline

sb.append("/n");

nextLine = getNextLine();

if (nextLine == null)

break;

}

for (int i = 0; i < nextLine.length(); i++) {

char c = nextLine.charAt(i);

if (c == quotechar) {

// this gets complex... the quote may end a quoted block, or escape another quote.

// do a 1-char lookahead:

if( inQuotes // we are in quotes, therefore there can be escaped quotes in here.

&& nextLine.length() > (i+1) // there is indeed another character to check.

&& nextLine.charAt(i+1) == quotechar ){ // ..and that char. is a quote also.

// we have two quote chars in a row == one quote char, so consume them both and

// put one on the token. we do *not* exit the quoted text.

sb.append(nextLine.charAt(i+1));

i++;

}else{

inQuotes = !inQuotes;

// the tricky case of an embedded quote in the middle: a,bc"d"ef,g

if(i>2 //not on the begining of the line

&& nextLine.charAt(i-1) != this.separator //not at the begining of an escape sequence

&& nextLine.length()>(i+1) &&

nextLine.charAt(i+1) != this.separator //not at the end of an escape sequence

){

sb.append(c);

}

}

} else if (c == separator && !inQuotes) {

tokensOnThisLine.add(sb.toString());

sb = new StringBuffer(); // start work on next token

} else {

sb.append(c);

}

}

} while (inQuotes);

tokensOnThisLine.add(sb.toString());

return (String[]) tokensOnThisLine.toArray(new String[0]);

}

/**

* Closes the underlying reader.

*

* @throws IOException if the close fails

*/

public void close() throws IOException{

br.close();

}

}

package au.com.bytecode.opencsv;

/**

Copyright 2005 Bytecode Pty Ltd.

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

*/

import java.io.IOException;

import java.io.PrintWriter;

import java.io.Reader;

import java.io.Writer;

import java.math.BigDecimal;

import java.sql.Clob;

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;

import java.sql.SQLException;

import java.sql.Time;

import java.sql.Timestamp;

import java.sql.Types;

import java.text.SimpleDateFormat;

import java.util.Iterator;

import java.util.List;

/**

* A very simple CSV writer released under a commercial-friendly license.

*

* @author Glen Smith

*

*/

public class CSVWriter {

private Writer rawWriter;

private PrintWriter pw;

private char separator;

private char quotechar;

private char escapechar;

private String lineEnd;

/** The character used for escaping quotes. */

public static final char DEFAULT_ESCAPE_CHARACTER = '"';

/** The default separator to use if none is supplied to the constructor. */

public static final char DEFAULT_SEPARATOR = ',';

/**

* The default quote character to use if none is supplied to the

* constructor.

*/

public static final char DEFAULT_QUOTE_CHARACTER = '"';

/** The quote constant to use when you wish to suppress all quoting. */

public static final char NO_QUOTE_CHARACTER = '/u0000';

/** The escape constant to use when you wish to suppress all escaping. */

public static final char NO_ESCAPE_CHARACTER = '/u0000';

/** Default line terminator uses platform encoding. */

public static final String DEFAULT_LINE_END = "/n";

private static final SimpleDateFormat

TIMESTAMP_FORMATTER =

new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");

private static final SimpleDateFormat

DATE_FORMATTER =

new SimpleDateFormat("dd-MMM-yyyy");

/**

* Constructs CSVWriter using a comma for the separator.

*

* @param writer

* the writer to an underlying CSV source.

*/

public CSVWriter(Writer writer) {

this(writer, DEFAULT_SEPARATOR);

}

/**

* Constructs CSVWriter with supplied separator.

*

* @param writer

* the writer to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries.

*/

public CSVWriter(Writer writer, char separator) {

this(writer, separator, DEFAULT_QUOTE_CHARACTER);

}

/**

* Constructs CSVWriter with supplied separator and quote char.

*

* @param writer

* the writer to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

*/

public CSVWriter(Writer writer, char separator, char quotechar) {

this(writer, separator, quotechar, DEFAULT_ESCAPE_CHARACTER);

}

/**

* Constructs CSVWriter with supplied separator and quote char.

*

* @param writer

* the writer to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

* @param escapechar

* the character to use for escaping quotechars or escapechars

*/

public CSVWriter(Writer writer, char separator, char quotechar, char escapechar) {

this(writer, separator, quotechar, escapechar, DEFAULT_LINE_END);

}

/**

* Constructs CSVWriter with supplied separator and quote char.

*

* @param writer

* the writer to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

* @param lineEnd

* the line feed terminator to use

*/

public CSVWriter(Writer writer, char separator, char quotechar, String lineEnd) {

this(writer, separator, quotechar, DEFAULT_ESCAPE_CHARACTER, lineEnd);

}

/**

* Constructs CSVWriter with supplied separator, quote char, escape char and line ending.

*

* @param writer

* the writer to an underlying CSV source.

* @param separator

* the delimiter to use for separating entries

* @param quotechar

* the character to use for quoted elements

* @param escapechar

* the character to use for escaping quotechars or escapechars

* @param lineEnd

* the line feed terminator to use

*/

public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd) {

this.rawWriter = writer;

this.pw = new PrintWriter(writer);

this.separator = separator;

this.quotechar = quotechar;

this.escapechar = escapechar;

this.lineEnd = lineEnd;

}

/**

* Writes the entire list to a CSV file. The list is assumed to be a

* String[]

*

* @param allLines

* a List of String[], with each String[] representing a line of

* the file.

*/

public void writeAll(List allLines) {

for (Iterator iter = allLines.iterator(); iter.hasNext();) {

String[] nextLine = (String[]) iter.next();

writeNext(nextLine);

}

}

protected void writeColumnNames(ResultSetMetaData metadata)

throws SQLException {

int columnCount = metadata.getColumnCount();

String[] nextLine = new String[columnCount];

for (int i = 0; i < columnCount; i++) {

nextLine[i] = metadata.getColumnName(i + 1);

}

writeNext(nextLine);

}

/**

* Writes the entire ResultSet to a CSV file.

*

* The caller is responsible for closing the ResultSet.

*

* @param rs the recordset to write

* @param includeColumnNames true if you want column names in the output, false otherwise

*

*/

public void writeAll(java.sql.ResultSet rs, boolean includeColumnNames) throws SQLException, IOException {

ResultSetMetaData metadata = rs.getMetaData();

if (includeColumnNames) {

writeColumnNames(metadata);

}

int columnCount = metadata.getColumnCount();

while (rs.next())

{

String[] nextLine = new String[columnCount];

for (int i = 0; i < columnCount; i++) {

nextLine[i] = getColumnValue(rs, metadata.getColumnType(i + 1), i + 1);

}

writeNext(nextLine);

}

}

private static String getColumnValue(ResultSet rs, int colType, int colIndex)

throws SQLException, IOException {

String value = "";

switch (colType)

{

case Types.BIT:

Object bit = rs.getObject(colIndex);

if (bit != null) {

value = String.valueOf(bit);

}

break;

case Types.BOOLEAN:

boolean b = rs.getBoolean(colIndex);

if (!rs.wasNull()) {

value = Boolean.valueOf(b).toString();

}

break;

case Types.CLOB:

Clob c = rs.getClob(colIndex);

if (c != null) {

value = read(c);

}

break;

case Types.BIGINT:

case Types.DECIMAL:

case Types.DOUBLE:

case Types.FLOAT:

case Types.REAL:

case Types.NUMERIC:

BigDecimal bd = rs.getBigDecimal(colIndex);

if (bd != null) {

value = "" + bd.doubleValue();

}

break;

case Types.INTEGER:

case Types.TINYINT:

case Types.SMALLINT:

int intValue = rs.getInt(colIndex);

if (!rs.wasNull()) {

value = "" + intValue;

}

break;

case Types.JAVA_OBJECT:

Object obj = rs.getObject(colIndex);

if (obj != null) {

value = String.valueOf(obj);

}

break;

case Types.DATE:

java.sql.Date date = rs.getDate(colIndex);

if (date != null) {

value = DATE_FORMATTER.format(date);;

}

break;

case Types.TIME:

Time t = rs.getTime(colIndex);

if (t != null) {

value = t.toString();

}

break;

case Types.TIMESTAMP:

Timestamp tstamp = rs.getTimestamp(colIndex);

if (tstamp != null) {

value = TIMESTAMP_FORMATTER.format(tstamp);

}

break;

case Types.LONGVARCHAR:

case Types.VARCHAR:

case Types.CHAR:

value = rs.getString(colIndex);

break;

default:

value = "";

}

if (value == null)

{

value = "";

}

return value;

}

private static String read(Clob c) throws SQLException, IOException

{

StringBuffer sb = new StringBuffer( (int) c.length());

Reader r = c.getCharacterStream();

char[] cbuf = new char[2048];

int n = 0;

while ((n = r.read(cbuf, 0, cbuf.length)) != -1) {

if (n > 0) {

sb.append(cbuf, 0, n);

}

}

return sb.toString();

}

/**

* Writes the next line to the file.

*

* @param nextLine

* a string array with each comma-separated element as a separate

* entry.

*/

public void writeNext(String[] nextLine) {

if (nextLine == null)

return;

StringBuffer sb = new StringBuffer();

for (int i = 0; i < nextLine.length; i++) {

if (i != 0) {

sb.append(separator);

}

String nextElement = nextLine[i];

if (nextElement == null)

continue;

if (quotechar != NO_QUOTE_CHARACTER)

sb.append(quotechar);

for (int j = 0; j < nextElement.length(); j++) {

char nextChar = nextElement.charAt(j);

if (escapechar != NO_ESCAPE_CHARACTER && nextChar == quotechar) {

sb.append(escapechar).append(nextChar);

} else if (escapechar != NO_ESCAPE_CHARACTER && nextChar == escapechar) {

sb.append(escapechar).append(nextChar);

} else {

sb.append(nextChar);

}

}

if (quotechar != NO_QUOTE_CHARACTER)

sb.append(quotechar);

}

sb.append(lineEnd);

pw.write(sb.toString());

}

/**

* Flush underlying stream to writer.

*

* @throws IOException if bad things happen

*/

public void flush() throws IOException {

pw.flush();

}

/**

* Close the underlying stream writer flushing any buffered content.

*

* @throws IOException if bad things happen

*

*/

public void close() throws IOException {

pw.flush();

pw.close();

rawWriter.close();

}

}

以下是达人对此API做的测试:
http://blog.csdn.net/lord_is_layuping/archive/2008/02/14/2095766.aspx

我也做了测试,实际上直接调用API中的方法即可,不过还是应该看懂源码,感觉写的不错,对提高水平有很大的帮助,以后在开源项目方面要多看看。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: