使用 Apache 的 commons-csv 实现 CSV 文件导出

1. CSV 简介

CSV全称是:Comma Separated Values (逗号分隔值)或者 Character Separated Values(字符分隔值)。其文件以纯文本形式存储表格数据(数字和文本)。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。每一行记录位于一个单独的行上,用回车换行符CRLF(也就是\r\n)分割。

  • 对于excel来说默认使用 ,进行分割数据。

  • 每一行记录最后一个字段后不能跟逗号

  • 每一行一条记录

  • 列为空需要指定 “”

  • 用回车换行符CRLF(\r\n)分割每条记录

  • 纯文本,使用某个字符集,比如ASCII、Unicode、EBCDIC或GB2312

2. 实现 CSV 文件导出

采用 Apache 开源的 commons-csv 包,详细内容参考 官网

2.1 使用
2.1.1 引入依赖
<dependency>  
    <groupId>org.apache.commons</groupId>  
    <artifactId>commons-csv</artifactId>  
    <version>1.7</version>  
</dependency>
2.1.2 API
  1. print(Object value); // 写入一个单元格数据
  1. printRecord(Iterable<?> values); // 写入一行数据
  1. printRecords(Iterable<?> values);// 写入多行数据

其他重载方法⬇️

2.2 封装一个导出方法
/**  
 * 导出 csv 文件  
 * [@param] out 输出流  
 * [@param] iter 数据 我这里传 List<List<Object>>   类型
 * [@param] charset 字符集编码  
 * [@param] header 表头  
 */  
public void exportCSVFile(OutputStream out, Iterable<?> iter, String charset, String... header) {  
	  try {  
		  // 写入bom, 防止中文乱码  
		  byte[] bytes = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};  
		  out.write(bytes);  

		  OutputStreamWriter osw = new OutputStreamWriter(out, charset);  
		  CSVFormat csvFormat = CSVFormat.EXCEL.withHeader(header);  

		  CSVPrinter csvPrinter = new CSVPrinter(osw, csvFormat);  
		  csvPrinter.printRecords(iter);  
		  csvPrinter.flush();  
		  csvPrinter.close();  
	  } catch (IOException e) {  
		  e.printStackTrace();  
	  }  
}
2.3 使用示例
List<List<Object>> lists = new ArrayList<>();  
​  
List<Object> list1 = new ArrayList<>();  
list1.add("张三");  
list1.add(18);  
list1.add("男");  
lists.add(list1);  
​  
List<Object> list2 = new ArrayList<>();  
list2.add("李四");  
list2.add(20);  
list2.add("女");  
lists.add(list2);  

String[] header = {"姓名", "年龄", "性别"};  

// 省略 out  

exportCSVFile(out, lists, "UTF-8", header);
  • Excel 打开

  • 文本编辑器打开

    张三,18,男

    李四,20,女

2.4 可能遇到的问题
  • 使用 Excel 打开出现中文乱码

    上面的示例代码采用的是写入 bom ,编码为 UTF-8 的方式解决的,也有其他方案是使用编码为 GBK。

  • 用 Excel 打开后,日期格式会变成 ### 或者 2019/01/01 以及较大数字会变成科学技术法

    写数据时加上制表符,一个制表符不够,就 2 个
    不要调用 printRecords(); 方法,而是通过遍历数据调用 csvPrinter.print("\t"+ 数据 +"\t");

    public void exportCSVFile(OutputStream out, Iterable<?> iter, String charset,String... header) {  
    	  try {  
    		  // 写入bom, 防止中文乱码  
    		  byte[] bytes = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};  
    		  out.write(bytes);  
    
    		  OutputStreamWriter osw = new OutputStreamWriter(out, charset);  
    		  CSVFormat csvFormat = CSVFormat.EXCEL.withHeader(header);  
    
    		  CSVPrinter csvPrinter = new CSVPrinter(osw, csvFormat);  
    		  Iterator<?> iterator = iter.iterator();  
    		  while (iterator.hasNext()) {  
    			  Collection list = (Collection)iterator.next();  
    			  // 开始写一行数据  
    			  list.forEach(c->{  
    				  try {  
    					  csvPrinter.print("\t" +c.toString() +"\t" );  
    				  } catch (IOException e) {  
    					  e.printStackTrace();  
    				  }  
    			  });  
    			  // 写完一行,需要换行  
    			  csvPrinter.println();  
    		  }  
    		  csvPrinter.flush();  
    		  csvPrinter.close();  
    	  } catch (IOException e) {  
    		  e.printStackTrace();  
    	  }  
    }
    

注意: 添加了制表符之后,用文本编辑器打开后,格式就会变得很难看, 如下图所示:

  • 写入的数据包含逗号,双引号等特殊字符时,导出的 csv 文件用文本编辑器打开,数据会用双引号包裹起来, 如下所示:

  • 通过 Excel 修改 CSV 文件会出现兼容性问题

Apache Commons CSV是一个Java库,可以用来读取、写入和处理CSV文件。如果你想使用它来导出字符串格式的数据,可以按照以下步骤进行操作: 1. 引入依赖 在你的项目中引入Apache Commons CSV的依赖。 Maven用户可以在pom.xml中添加以下代码块: ``` <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv</artifactId> <version>1.8</version> </dependency> ``` Gradle用户可以在build.gradle中添加以下代码: ``` implementation 'org.apache.commons:commons-csv:1.8' ``` 2. 创建CSVPrinter对象 创建一个CSVPrinter对象来写入CSV数据到字符串中。CSVPrinter的构造函数需要一个Writer对象作为参数,可以使用StringWriter来创建一个Writer对象。 ``` StringWriter writer = new StringWriter(); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT); ``` 3. 写入数据 使用CSVPrinter的printRecord方法将数据写入CSV文件中。printRecord方法接受一个可变参数列表,可以传递任意数量的值。 ``` csvPrinter.printRecord("Name", "Age", "Gender"); csvPrinter.printRecord("John", 25, "Male"); csvPrinter.printRecord("Jane", 30, "Female"); ``` 4. 获取字符串格式的数据 调用StringWriter的toString方法可以获取CSV数据的字符串格式。 ``` String csvData = writer.toString(); ``` 完整的代码示例: ``` StringWriter writer = new StringWriter(); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT); csvPrinter.printRecord("Name", "Age", "Gender"); csvPrinter.printRecord("John", 25, "Male"); csvPrinter.printRecord("Jane", 30, "Female"); String csvData = writer.toString(); ``` csvData字符串的值为: ``` Name,Age,Gender John,25,Male Jane,30,Female ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值