CSV工具类


import org.apache.commons.io.ByteOrderMark;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * CSV工具类
 */
public class CSVUtil {

    private static final Logger logger = LoggerFactory.getLogger(CSVUtil.class);

    /**
     * 换列符
     */
    private static final String LF = ",";
    /**
     * 换行符
     */
    private static final String HF = "\r\n";

    /**
     * 写CSV并转换为字节流
     *
     * @param columns  表头
     * @param fields   属性
     * @param cellList 数据
     * @return
     */
    public static byte[] writeDataAfterToBytes(String[] columns, String[] fields, List<Object> cellList) {
        byte[] bytes = new byte[0];
        ByteArrayOutputStream byteArrayOutputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            outputStreamWriter = new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            //excel文件需要通过文件头的bom来识别编码,而CSV文件格式不自带bom,所以写文件时,需要先写入bom头,否则excel打开乱码
            bufferedWriter.write(new String(ByteOrderMark.UTF_8.getBytes()));
            //写表头
            StringBuilder sb = new StringBuilder();
            String tableHeader = String.join(LF, columns);
            sb.append(tableHeader + HF);
            for (Object obj : cellList) {
                Map<String, Object> map = obj instanceof Map ? (Map<String, Object>) obj : MapUtil.transBean2Map(obj);
                for (int i = 0; i < fields.length; i++) {
                    Object value = map.get(fields[i]);
                    sb.append(formatValue(value) + LF);
                }
                sb.append(HF);
            }
            bufferedWriter.write(sb.toString());
            bufferedWriter.flush();
            //把输出流转换字节流
            bytes = byteArrayOutputStream.toString(StandardCharsets.UTF_8.name()).getBytes();
            return bytes;
        } catch (IOException e) {
            logger.error("writeDataAfterToBytes IOException:{}", e.getMessage(), e);
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
                if (outputStreamWriter != null) {
                    outputStreamWriter.close();
                }
                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.close();
                }
            } catch (IOException e) {
                logger.error("iostream close IOException:{}", e.getMessage(), e);
            }
        }
        return bytes;
    }

    /**
     * 生成CSV文件到指定目录
     *
     * @param columns  表头
     * @param fields   数据集对应字段名
     * @param cellList 数据集
     * @param filePath 生成路径及文件名
     */
    public static void writeDataAfterToFile(String[] columns, String[] fields, List<Object> cellList, String filePath) {
        byte[] bytes = new byte[0];
        BufferedWriter bufferedWriter = null;
        try {
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), StandardCharsets.UTF_8));
            //excel文件需要通过文件头的bom来识别编码,而CSV文件格式不自带bom,所以写文件时,需要先写入bom头,否则excel打开乱码
            bufferedWriter.write(new String(ByteOrderMark.UTF_8.getBytes()));
            //写表头
            StringBuilder sb = new StringBuilder();
            String tableHeader = String.join(LF, columns);
            sb.append(tableHeader + HF);
            for (Object obj : cellList) {
                Map<String, Object> map = obj instanceof Map ? (Map<String, Object>) obj : MapUtil.transBean2Map(obj);
                for (int i = 0; i < fields.length; i++) {
                    Object value = map.get(fields[i]);
                    sb.append(formatValue(value) + LF);
                }
                sb.append(HF);
            }
            bufferedWriter.write(sb.toString());
            bufferedWriter.flush();
        } catch (IOException e) {
            logger.error("writeDataAfterToBytes IOException:{}", e.getMessage(), e);
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                logger.error("iostream close IOException:{}", e.getMessage(), e);
            }
        }
    }

    /**
     * 格式化数据
     *
     * @param cellVal 内容
     */
    public static String formatValue(Object cellVal) {
        String value = null;
        if (cellVal == null || String.class.equals(cellVal.getClass())) {
            value = StringUtil.isHref(cellVal);
        } else if (Integer.class.equals(cellVal.getClass()) || int.class.equals(cellVal.getClass())
                || Long.class.equals(cellVal.getClass()) || long.class.equals(cellVal.getClass())
                || Double.class.equals(cellVal.getClass()) || double.class.equals(cellVal.getClass())
                || Float.class.equals(cellVal.getClass()) || float.class.equals(cellVal.getClass())
                || BigDecimal.class.equals(cellVal.getClass())) {
            value = cellVal.toString();
        } else if (Date.class.equals(cellVal.getClass())) {
            value = DateUtil.format((Date) cellVal, com.zjm.util.DateUtil.DATETIME_PATTERN);
        } else if (Timestamp.class.equals(cellVal.getClass())) {
            value = DateUtil.format((Timestamp) cellVal, com.zjm.util.DateUtil.DATETIME_PATTERN);
        } else {
            value = StringUtil.isNull(cellVal);
        }
        return value;
    }

    /**
     * 设置下载响应
     *
     * @param fileName
     * @param bytes
     * @param response
     */
    public static void responseSetProperties(String fileName, byte[] bytes, HttpServletResponse response) {
        try {
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
            response.setContentType("application/csv");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "max-age=30");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(bytes);
            outputStream.flush();
        } catch (IOException e) {
            logger.error("iostream error:{}", e.getMessage(), e);
        }
    }
}

当然,我可以为您提供一个简单的 Java CSV 工具类的源码示例。以下是一个基本的实现,可以用于读取和写入 CSV 文件。 ```java import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class CSVUtils { private static final char DEFAULT_SEPARATOR = ','; private static final char DEFAULT_QUOTE = '"'; public static List<String[]> readCSV(String csvFile) { List<String[]> lines = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) { String line; while ((line = br.readLine()) != null) { String[] values = parseLine(line); lines.add(values); } } catch (IOException e) { e.printStackTrace(); } return lines; } private static String[] parseLine(String line) { return parseLine(line, DEFAULT_SEPARATOR, DEFAULT_QUOTE); } private static String[] parseLine(String line, char separator, char quoteChar) { List<String> values = new ArrayList<>(); StringBuilder sb = new StringBuilder(); boolean inQuotes = false; for (char c : line.toCharArray()) { if (c == quoteChar) { inQuotes = !inQuotes; } else if (c == separator && !inQuotes) { values.add(sb.toString().trim()); sb.setLength(0); } else { sb.append(c); } } values.add(sb.toString().trim()); return values.toArray(new String[0]); } public static void writeCSV(String csvFile, List<String[]> lines) { try (BufferedWriter bw = new BufferedWriter(new FileWriter(csvFile))) { for (String[] values : lines) { String line = joinLine(values); bw.write(line); bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } } private static String joinLine(String[] values) { return joinLine(values, DEFAULT_SEPARATOR, DEFAULT_QUOTE); } private static String joinLine(String[] values, char separator, char quoteChar) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < values.length; i++) { if (i > 0) { sb.append(separator); } sb.append(quoteChar); sb.append(values[i]); sb.append(quoteChar); } return sb.toString(); } } ``` 这个工具类提供了两个主要方法: - `readCSV`:用于从指定的 CSV 文件中读取数据,并将每一行的值存储在一个 `List<String[]>` 中。 - `writeCSV`:用于将数据写入到指定的 CSV 文件中。 您可以根据需要修改这个工具类,以满足特定的 CSV 格式要求或增加更多功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值