JAVA CSV内容生成(针对导出数据量大,excel不适合)

1 篇文章 0 订阅

CSV内容生成(针对导出数据量大,excel不适合)


)

众所周知,csv文件编辑器打开,列之间以“,”逗号相隔

问:列字段值包含逗号应该怎么办?

答:字段用双引号包起来。

问:若该字段值也有双引号怎么办?

答:在双引号前添加一个双引号,字段整体再用双引号包起来。

举例

在这里插入图片描述

代码参考

public class CSVUtils {
    private CSVUtils() {
    }

    /* 列分隔符 */
    private static final String COLUMN_SEPARATOR = ",";

    /* 行分隔符 */
    private static final String ROW_SEPARATOR = "\r\n";

    /* 字符:引号 */
    private static final String MARK_QUAT = "\"";

    public static <T> String createByBean(String[] header, List<T> data) {
        return create(header, data.stream().filter(Objects::nonNull).map(row ->
                ReflectUtils.getFields(row.getClass()).stream().filter(field -> !"serialVersionUID".equals(field.getName()))
                        .map(field -> {
                            try {
                                field.setAccessible(true);
                                return field.get(row);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }).collect(toList())
        ).collect(toList()));
    }
    
    public static String create(String[] header, List<List<Object>> data) {
        StringBuffer buf = new StringBuffer();
        AssertBiz.notEmpty(header, "header is Empty.");
        buf.append(Arrays.stream(header).map(CSVUtils::convert).collect(joining(COLUMN_SEPARATOR)));
        buf.append(ROW_SEPARATOR);
        data.stream().filter(Objects::nonNull).forEach(row -> {
            buf.append(row.stream().map(CSVUtils::convert).collect(joining(COLUMN_SEPARATOR)));
            buf.append(ROW_SEPARATOR);
        });
        return buf.toString();
    }

    private static String convert(Object column) {
        if (null == column) {
            return "";
        }
        if (column instanceof String) {
            return stringAlter(String.class.cast(column));
        }
        if (column instanceof Date) {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date.class.cast(column));
        }
        return column.toString();
    }

    private static String stringAlter(String column) {
        if (null == column || StringUtils.isBlank(column)) {
            return "";
        }
        if (column.contains(MARK_QUAT)) {
            int[] indexs = indexOf(column, MARK_QUAT);
            StringBuilder tmp = new StringBuilder(column);
            IntStream.range(0, indexs.length).forEach(i -> tmp.insert(i + indexs[i], MARK_QUAT));
            return MARK_QUAT + tmp.toString() + MARK_QUAT;
        }
        if (column.contains(COLUMN_SEPARATOR)) {
            return MARK_QUAT + column + MARK_QUAT;
        }
        return column;
    }

    private static int[] indexOf(String source, String target) {
        List<Integer> indexs = new ArrayList<>();
        int tmp = source.indexOf(target);
        while (tmp > -1) {
            indexs.add(tmp);
            tmp = source.indexOf(target, tmp + 1);
        }
        return indexs.stream().mapToInt(Integer::valueOf).toArray();
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值