Java CSV导出

1.Maven依赖

//用的是javacsv开源工具
 <dependency>
      <groupId>net.sourceforge.javacsvgroupId>
      <artifactId>javacsvartifactId>
      <version>2.0version>
    dependency>

    
    <dependency>
      <groupId>commons-collectionsgroupId>
      <artifactId>commons-collectionsartifactId>
      <version>3.2.2version>
    dependency>

    
    <dependency>
      <groupId>commons-langgroupId>
      <artifactId>commons-langartifactId>
      <version>2.6version>
    dependency>

2.工具类

import com.csvreader.CsvWriter;
import org.apache.commons.collections.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;

/**
 * Created by John on 2017/12/30.
 */
public class CsvUtil {

    public static void main(String[] args) {
        String filePath = "D://study.csv";
        CsvWriter csvWriter = new CsvWriter(filePath, ',', Charset.forName("GBK"));
        // 写表头
        String[] headers = {"编号", "姓名", "年龄"};
        String[] content = {"12365", "张山", "34"};
        try {
            csvWriter.writeRecord(headers);
            csvWriter.writeRecord(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
        csvWriter.close();
    }

    /**
     * 导出.csv文件在浏览器端下载(可选择保存路径)
     *
     * @param fileName     文件名
     * @param columnKeyMap 列名-属性,这里用LinkedHashMap是为了保证导出去的Excel列名顺序不会乱
     * @param dataList     数据源
     * @param response     HttpServletResponse
     */
    public static void writeData(String fileName, LinkedHashMap columnKeyMap, List> dataList, HttpServletResponse response) {
        if (Objects.isNull(columnKeyMap) || columnKeyMap.isEmpty()) {
            throw new RuntimeException("Excel没有设置列名和对应的属性!");
        }

        if (CollectionUtils.isNotEmpty(dataList)) {
            //写入临时文件
            File tempFile = null;
            List recordData = null;
            try {
                tempFile = File.createTempFile(fileName, ".csv");
                // 创建CSV写对象
                CsvWriter csvWriter = new CsvWriter(tempFile.getCanonicalPath(), ',', Charset.forName("UTF-8"));
                // 写入表头
                csvWriter.writeRecord(columnKeyMap.values().toArray(new String[columnKeyMap.values().size()]));

                //第一种写入方式
                /*for (Map data:dataList) {
                    for (String key:columnKeyMap.keySet()){
                        csvWriter.write(Objects.isNull(data.get(key)) ? "":data.get(key).toString());
                    }
                    csvWriter.endRecord();
                }*/

                //第二种写入方式
                for (Map data : dataList) {
                    //先将每一行record的数据准备好,封装成一个String[]
                    recordData = new ArrayList<>(data.size());
                    for (String key : columnKeyMap.keySet()) {
                        recordData.add(Objects.isNull(data.get(key)) ? "" : data.get(key).toString());
                    }
                    csvWriter.writeRecord(recordData.toArray(new String[recordData.size()]));
                }

                csvWriter.close();

                /**
                 * 写入csv结束,写出流,设置响应头直接在浏览器端下载
                 * 因为csvWriter不提供类似Poi的写入流workbook.write(out);
                 * 故在csv写入数据完之后,要手动把文件写入流;
                 */
                response.reset();
                response.setContentType("application/csv");
                response.setHeader("content-disposition", "attachment; filename=" + fileName + ".csv");
                File fileLoad = new File(tempFile.getCanonicalPath());
                String fileLength = String.valueOf(fileLoad.length());
                response.setHeader("Content_Length", fileLength);
                java.io.FileInputStream in = new java.io.FileInputStream(fileLoad);
                java.io.OutputStream out = response.getOutputStream();
                int eof;
                byte[] b = new byte[2048];
                while ((eof = in.read(b)) != -1) {
                    out.write(b, 0, eof); //每次写入out 2048字节
                }
                in.close();
                out.close();

                //下载完成,删除临时文件
                tempFile.delete();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 除了可以查询出所有要的数据一次性导出外,
     * 还可以边查边导,循环写入,只不过这种方式没法做到通用性,
     * 对于数据量特别大的可以考虑
     */
    public static void batchWriteData(String fileName, LinkedHashMap columnKeyMap, HttpServletResponse response) {
        if (Objects.isNull(columnKeyMap) || columnKeyMap.isEmpty()) {
            throw new RuntimeException("Excel没有设置列名和对应的属性!");
        }
        //伪代码
        int totalRows = studentService.countAll(param);
        if (totalRows > 0) {
            //写入临时文件
            File tempFile = null;
            List recordData = null;
            try {
                tempFile = File.createTempFile(fileName, ".csv");
                // 创建CSV写对象
                CsvWriter csvWriter = new CsvWriter(tempFile.getCanonicalPath(), ',', Charset.forName("UTF-8"));
                // 写入表头
                csvWriter.writeRecord(columnKeyMap.values().toArray(new String[columnKeyMap.values().size()]));

                int loop = 0;
                int limit = 2000;//每次循环写入2000条数据
                while (totalRows > 0){
                    int startRow = loop * limit;
                    Map pageParam = new HashMap<>();
                    pageParam.put("startRow",startRow);
                    pageParam.put("pageSize",limit);
                    List list = studentService.pageQuery(pageParam);
                    /**
                     * 这里可以把list中的POJO转换成Map,因为我们并不总是需要所有属性,
                     * 还有可以需要对属性值做一些转换,如时间,金钱格式的转换,或者枚举价值的中文描述
                     */
                    List> dataMap = studentService.listToMap(list);
                    for (Map data:dataMap){
                        //先将每一行record的数据准备好,封装成一个String[]
                        recordData = new ArrayList<>(data.size());
                        for (String key : columnKeyMap.keySet()) {
                            recordData.add(Objects.isNull(data.get(key)) ? "" : data.get(key).toString());
                        }
                        csvWriter.writeRecord(recordData.toArray(new String[recordData.size()]));
                    }

                    loop++;
                    totalRows = totalRows - limit;
                }

                csvWriter.close();

                /**
                 * 写入csv结束,写出流,设置响应头直接在浏览器端下载
                 * 因为csvWriter不提供类似Poi的写入流workbook.write(out);
                 * 故在csv写入数据完之后,要手动把文件写入流;
                 */
                response.reset();
                response.setContentType("application/csv");
                response.setHeader("content-disposition", "attachment; filename=" + fileName + ".csv");
                File fileLoad = new File(tempFile.getCanonicalPath());
                String fileLength = String.valueOf(fileLoad.length());
                response.setHeader("Content_Length", fileLength);
                java.io.FileInputStream in = new java.io.FileInputStream(fileLoad);
                java.io.OutputStream out = response.getOutputStream();
                int eof;
                byte[] b = new byte[2048];
                while ((eof = in.read(b)) != -1) {
                    out.write(b, 0, eof); //每次写入out 2048字节
                }
                in.close();
                out.close();

                //下载完成,删除临时文件
                tempFile.delete();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

}

3.使用示例

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Created by John on 2017/12/30.
 */
@Controller
@EnableAutoConfiguration
public class SampleController {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }

    @RequestMapping("/csv")
    public void csv(HttpServletResponse response){
        // 创建CSV写对象
        List> ls=new ArrayList<>();
        /*for (int i = 0; i <10000; i++) {
            Student s=new Student();
            s.setName("小帅"+i);
            s.setAge(i);
            s.setScore("100"+i);
            s.setSex("男"+i);
            ls.add(s);
        }*/
        Map map = null;
        for (int i=0;i<100000;i++){
            map = new HashMap<>();
            map.put("name","你妹" + i);
            map.put("age",i);
            map.put("score",i);
            map.put("sex","男");
            ls.add(map);
        }
        String fileName = "vehicle";
        LinkedHashMap keyMap = new LinkedHashMap<>();
        keyMap.put("name","姓名");
        keyMap.put("age","年龄");
        keyMap.put("score","编号");
        keyMap.put("sex","性别");
        long start = System.currentTimeMillis();
        CsvUtil.writeData(fileName,keyMap,ls,response);
        System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }
}

你可能感兴趣的:(Utils)