欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java导出csv文件工具类

程序员文章站 2022-05-26 19:09:08
...
import com.csvreader.CsvWriter;
import lombok.extern.slf4j.Slf4j;

import javax.persistence.Column;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;

import java.nio.charset.Charset;
import java.util.List;

@Slf4j
public class CsvUtil {

    // 文件后缀
    public static final String SUFFIX = ".csv";
    // 字符
    public static final String CHARSET = "UTF-8";
    public static final int SIZE = 1024;


    /**
     *
     * @param exportData 待导出的数据
     * @param clazz 实体对象
     * @param outPutPath 文件路径
     * @param fileName 文件名
     * @param <T> T
     * @return csvFileFullName
     */
    public static <T> String createCsvFile(List<T> exportData, Class<T> clazz, String outPutPath, String fileName) {
        File csvFile;
        CsvWriter csvWtriter = null;
        String csvFileFullName = null;
        try {
            File file = new File(outPutPath);
            if (!file.exists()) {
                if (!file.mkdirs()) {
                    log.info("======================================路径文件创建失败==============================");
                    return null;
                }
            }
            //定义文件名格式并创建
            csvFileFullName = outPutPath + File.separator + fileName + SUFFIX;
            csvFile = new File(csvFileFullName);
            if (csvFile.exists()) {
                if (!csvFile.delete()) {
                    log.info("======================================旧文件删除失败==============================");
                    return null;
                }
            }
            if (csvFile.createNewFile()) {
                log.info("======================================csv文件创建成功==============================");
            }

            csvWtriter = new CsvWriter(csvFile.getCanonicalPath(), ',', Charset.forName(CHARSET));

            // 写入文件内容
            if (!exportData.isEmpty()) {
                // 写入文件头部
                String[] headerColums = getHeaders(exportData.get(0), clazz);
                csvWtriter.writeRecord(headerColums);
                for (T data : exportData) {
                    String[] rowColums = getContentRow(data, clazz);
                    csvWtriter.writeRecord(rowColums,true);
                }
            }
            log.info("======================================csv文件已生成====================================");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (csvWtriter != null) {
                csvWtriter.close();
            }
        }

        return csvFileFullName;
    }

	/**
     * @param data 实体对象,  使用@Column(name="手机号")注解定义文件的表头字段名
     */
    private static <T> String[] getHeaders(T data, Class<T> clazz) {
        T u = clazz.cast(data);
        Field[] fields = u.getClass().getDeclaredFields();
        String[] headerColums = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            // 获取对应的注解值
            String columnName = fields[i].getAnnotation(Column.class).name();
            headerColums[i] = columnName;
        }

        return headerColums;
    }


    private static <T> String[] getContentRow(T data, Class<T> clazz) throws IllegalAccessException {
        T u = clazz.cast(data);
        Field[] fields = u.getClass().getDeclaredFields();
        String[] rowColums = new String[fields.length];
        // 遍历对象的所有属性
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            String value = fields[i].get(u) == null ? "" : String.valueOf(fields[i].get(u));
            // 每个value后面拼接 "\u0009"防止日期显示不正常,以及大数字显示成科学计数法
            rowColums[i] = value + "\u0009";
        }

        return rowColums;
    }


    public static void export(HttpServletResponse response, String fileFullName) throws IOException, RuntimeException {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(fileFullName);
            int len;
            byte[] buffer = new byte[SIZE];
            out = response.getOutputStream();
            // 防止中文乱码
            out.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            response.reset();
            response.setContentType("application/csv;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileFullName.substring(fileFullName.lastIndexOf("/") + 1), CHARSET));
            response.setCharacterEncoding(CHARSET);
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 删除临时文件
            if (!deleteFile(fileFullName)) {
                log.info("=================================临时文件删除失败=========================");
            }
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    log.info("=================================输入流关闭失败=========================");
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    log.info("=================================输出流关闭失败=========================");
                }
            }
        }
    }


    public static boolean deleteFile(String pathName) {
        //根据路径创建文件对象
        File file = new File(pathName);
        //路径是个文件时删除文件
        if (file.isFile()) {
            return file.delete();
        }
        return false;
    }

}