添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本文结构:

  • 废话
  • 动手读csv
  • 写csv

工作中需要读写csv,由于csv 文件较大,数据比较多,所以需要选择一个速度快的csv 读取插件。经过比较选择opencsv 。官方解释:Opencsv是一个易于使用的CSV(逗号分隔值)解析器库。之所以开发它,是因为当时所有CSV解析器都没有商业友好的许可证。Java 7是目前支持的最小版本。

Opencsv

Opencsv支持您可能想要做的所有基本CSV类型的事情:

  • 每行的任意数量的值。

  • 忽略引用元素中的逗号。

  • 处理带有嵌入式回车的带引号的条目(即跨越多行的条目)。

  • 可配置的分隔符和引号字符(或使用合理的默认值)。

    所有这些事情都可以通过可塑性方法的表现来完成阅读和写作:

  • 往返于一个字符串数组。

  • 来自带注释的bean。

  • 来自数据库一次读取所有条目,或使用Iterator风格的模型

废话不多说:官方文档[http://opencsv.sourceforge.net/]

跟我一起做 读csv

<dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>4.2</version>
        </dependency>

读取csv 映射为对象(此时会按照csv 的顺序进行映射全量,如果需要只取csv中的部分列则看下一部分)

 public  static <T> List<T> getCsvData(Class<T> clazz) {
        InputStreamReader in=null;
        try {
            in = new InputStreamReader(new FileInputStream("xxxx.csv"), "gbk");
        } catch (Exception e) {
        System.out.println(System.currentTimeMillis());
        HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
        strategy.setType(clazz);
        CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(in)
                .withSeparator(',')
                .withQuoteChar('\'')
                .withMappingStrategy(strategy).build();
        List<T> list= csvToBean.parse();
        System.out.println(System.currentTimeMillis());
        System.out.println(list.size());
    return list;    

如果只需要取csv 中部分列的值映射到对象里,则只需要在对象中添加注解 @CsvBindByName即可

(required = true ) 参数指csv 中该列的值不能为空

public class Student {
    @CsvBindByName(column = "name", required = true)
    private String name;
    @CsvBindByName(column = "address", required = false)
    private String address;
    @CsvBindByName(column = "age", required = false)
    private Integer age;
    //不需要从csv中取值
		private Integer sex;

当然这样的取值还是不够自由,那么Opencsv还提供了更自由的方式

读取csv 的任意行和列。而且csv很大的话,速度也很快哦,只要内存跟得上。

minLine 为读取的起始行,当然你也可以再设置一个结束行的字段,每次判断行号。当然也需要自己设置一个行号,每次自增。

 private static Set<String> readCsv(int minLine,  String path) throws IOException {
        Integer lineNum = minLine;
        FileReader fReader = new FileReader(new File(path));
        CSVReader csvReader = new CSVReader(fReader);
        String[] values;
        Set<String> set = new HashSet<>();
        //跳过前方minLine 条数据
        csvReader.skip(minLine);
        while ((values = csvReader.readNext()) != null) {
                // values 是一个数组,存储了csv当前行的所有元素,在此你可以将数组中的元素取出来放入你的对象中
                set.add(StringUtils.join(values, Constants.CSV_SPLIT));
            lineNum++;
        return set;
	public static void main(String[] args) throws Exception {
		File file = new File("xxx.csv");
		Writer writer = new FileWriter(file);
    //分隔符默认为逗号
		CSVWriter csvWriter = new CSVWriter(writer);
		String[] strs = {"abc" , "abc" , "abc"};
		csvWriter.writeNext(strs);
		csvWriter.close();

写 csv 方法2

此方法不用引入其他依赖,jdk自身的就够了,目前我使用此方法

controller 层

 @GetMapping("/csv")
    public void csv(HttpServletRequest request, HttpServletResponse response, String keyword) throws Exception{
       //查询数据库获取导出数据
        List<Student> list = xxxService.exportList(keyword);
        String fileName = ExportUtil.getFileName(request, "测试数据" + System.currentTimeMillis() + ".csv");
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM.toString());
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
		// 表头
        LinkedHashMap<String, Object> header = new LinkedHashMap<>();
        header.put("1", "姓名");
        header.put("2", "年龄");
        header.put("3", "性别");
        header.put("4", "地址");
        List<LinkedHashMap<String, Object>> data = new ArrayList<>();
        data.add(header);
        list.forEach(x->{
            LinkedHashMap<String, Object> body = new LinkedHashMap<>();
            body.put("1", x.getName());
            body.put("2", x.getAge());
            body.put("3", x.getSex());
            body.put("4", x.getAddress());
            data.add(body);
        FileCopyUtils.copy(ExportUtil.exportCSV(data), response.getOutputStream());

ExportUtil 工具类

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
 * @author yyb
 * @time 2020/3/9
public class ExportUtil {
    public static byte[] exportCSV(List<LinkedHashMap<String, Object>> exportData) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BufferedWriter buffCvsWriter = null;
        try {
            buffCvsWriter = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
            // 将body数据写入表格
            for (Iterator<LinkedHashMap<String, Object>> iterator = exportData.iterator(); iterator.hasNext(); ) {
                fillDataToCsv(buffCvsWriter, iterator.next());
                if (iterator.hasNext()) {
                    buffCvsWriter.newLine();
            // 刷新缓冲
            buffCvsWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (buffCvsWriter != null) {
                try {
                    buffCvsWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
        return out.toByteArray();
    private static void fillDataToCsv(BufferedWriter buffCvsWriter, LinkedHashMap row) throws IOException {
        Map.Entry propertyEntry;
        for (Iterator<Map.Entry> propertyIterator = row.entrySet().iterator(); propertyIterator.hasNext(); ) {
            propertyEntry = propertyIterator.next();
            buffCvsWriter.write("\"" + propertyEntry.getValue().toString() + "\"");
            if (propertyIterator.hasNext()) {
                buffCvsWriter.write(",");
    public static  String getFileName(HttpServletRequest request, String name) throws UnsupportedEncodingException {
        String userAgent = request.getHeader("USER-AGENT");
        return userAgent.contains("Mozilla") ? new String(name.getBytes(), "ISO8859-1") : name;

好了,打完收工。

CSV是一种通用的、相对简单的文件格式,其文件以纯文本形式存储表格数据(数字和文本)。可以通过下面的代码进行测试,可以发现能正常的进行读取和输出csv格式的文件。由于CSV是一种纯文本的文件,因此其具有以下几个特点。CSV是纯文本文件,可以使用任何文本编辑器进行编辑。java中读取和存储数据到CSV格式的文件中。支持追加模式写入,节省内存。CSV的文件行数没有限制。... import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import java.io.*; 1.读取文件import java.io.BufferedReader; import java.io.FileReader; public class TestRead { public static void main(String[] args) { try { BufferedReader reader = new Buffer 在本教程中,我们将学习如何读取 CSV 文件并将其内容复制到数组或列表中。在本教程中,我们将使用仅包含三条记录的简单 CSV 文件。但是在读取更复杂的 CSV 文件时,我们可能无法获得预期的结果。请注意,我们不能使用此方法读取更复杂的 CSV 文件或逗号本身为值的文件。如果我们尝试读取此文件,则以下数据存储在列表中。我们将简单地读取文件的每一行,然后使用逗号作为分隔符将其拆分。让我们将上面的代码用于CSV文件,其中我们有一个值为逗号的单元格。是一个CSV文件解析库,可以使从CSV文件读取变得更加容易。 实际工作中,很多数据都存在csv文件中,使用 java语言开发的时候,有的时候需要读取文件,或者将csv文件导入到数据库中,commons-csv作为三方类库,简化了读取操作! 最近在做嵌入式Linux平台上的服务器,使用的工具是Java。在项目中一方面要将所有数据记录在日志文件中,存储于嵌入式Linux平台上;另一方面要将实时数据存放在一个表格里,随时供网络查询。日志文件我们曾经选用过txt文件,这个最简单;excel文件,使用jxl;使用过sqlLite嵌入式数据库,使用第三方的java库。调试通过,运行的还算不错。不过遇到了一个java虚拟机内存不足的问题,我们将虚... public static ArrayList<String> readCsvByCsvReader(String filePath) { ArrayList<String> strList = n