CSV内容生成(针对导出数据量大,excel不适合)
标签:  后端
229 ·
0 ·
2020-08-15 23:17
最新一次编辑的原因:

    总所周知,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 BizException(e.getMessage(), 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();
    }


}

本作品系原创,采用《署名-非商业性使用-禁止演绎4.0 国际》许可协议.转载请说明出处
本文链接:https://www.upupor.com/u/20081523171628645376 复制分享

无评论内容,快来评论吧