java-tocsv

1、依赖

<dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.69</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.12</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

2、注解类

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyExcelName {
    String value() default "";
}

3、实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class District implements Serializable {
    /**
     * 地址编码
     */
    @MyExcelName("编码")
    private String code;
    /**
     * 地址名称
     */
    @MyExcelName("名称")
    private String name;
    /**
     * 地址父级编码
     */
    @MyExcelName("父级编码")
    private String parentCode;
    /**
     * 当前地区对应的全称
     */
    @MyExcelName("全称")
    private String fullName;

}

4、工具类

/**
 * <p>描述 : csv帮助类
 *
 * <p>路径 : cn.tjhis.utils
 *
 * <p>工程 : ExcelExport
 *
 * <p>作者 : wanghx
 *
 * <p>日期 : 2023-03-04 05:56
 *
 * @author : Administrator
 */
public class MyCsvFileUtil {
    /**
     * 文件后缀
     */
    private static final String FILE_SUFFIX = ".csv";
    /**
     * 分隔符
     */
    private static final String CSV_DELIMITER = ",";
    /**
     * 换行符
     */
    private static final String CSV_TAIL = "\r\n";
    /**
     * 文件名称
     */
    protected static final String DATE_STR_FILE_NAME = "yyyyMMddHHmmssSSS";

    /**
     * 将字符串转成csv文件
     */
    private static void createCsvFile(String savePath, String contextStr) throws IOException {

        File file = new File(savePath);
        //创建文件
        file.createNewFile();
        //创建文件输出流
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //将指定字节写入此文件输出流
        fileOutputStream.write(contextStr.getBytes("gbk"));
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    /**
     * 写文件
     *
     * @param fileName 文件名称
     * @param content  内容
     */
    private static void writeFile(String fileName, String content) {
        FileOutputStream fos = null;
        OutputStreamWriter writer = null;
        try {
            fos = new FileOutputStream(fileName, true);
            writer = new OutputStreamWriter(fos, "GBK");
            writer.write(content);
            writer.flush();
        } catch (Exception e) {
            StaticLog.error("写文件异常|{}", e);
        } finally {
            if (fos != null) {
                //关闭流
                IOUtils.closeQuietly(fos);
            }
            if (writer != null) {
                IOUtils.closeQuietly(writer);
            }
        }
    }

    /**
     * 构建文件名称
     *
     * @param dataList list 数据
     * @return 文件名称
     */
    private static String buildCsvFileFileName(List dataList) {
        return dataList.get(0).getClass().getSimpleName() + new SimpleDateFormat(DATE_STR_FILE_NAME).format(new Date()) + FILE_SUFFIX;
    }

    /**
     * 构建excel 标题行名
     *
     * @param dataList list 数据
     * @return 标题
     */
    private static String buildCsvFileTableNames(List dataList) {
        Map<String, Object> map = toMap(dataList.get(0));
        StringBuilder tableNames = new StringBuilder();
        for (String key : map.keySet()) {
            tableNames.append(key).append(MyCsvFileUtil.CSV_DELIMITER);
        }
        return tableNames.append(MyCsvFileUtil.CSV_TAIL).toString();
    }

    /**
     * 构建excel 标题行名
     *
     * @param dataList list 数据
     * @return 标题
     */
    private static String buildCsvFileTableNamesNew(List<String> dataList) {

        StringBuilder tableNames = new StringBuilder();
        for (String name : dataList) {
            tableNames.append(name).append(MyCsvFileUtil.CSV_DELIMITER);
        }
        return tableNames.append(MyCsvFileUtil.CSV_TAIL).toString();
    }

    /**
     * 构建excel内容
     *
     * @param dataLists list 数据
     * @return 内容
     */
    private static String buildCsvFileBodyMap(List dataLists) {
        // 不管你传什么玩意,都搞成Map
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Object o : dataLists) {
            mapList.add(toMap(o));
        }
        // 然后利用csv格式,对着map拼接数据
        StringBuilder lineBuilder = new StringBuilder();
        for (Map<String, Object> rowData : mapList) {
            for (String key : rowData.keySet()) {
                Object value = rowData.get(key);
                if (Objects.nonNull(value)) {
                    lineBuilder.append(value).append(MyCsvFileUtil.CSV_DELIMITER);
                } else {
                    lineBuilder.append("--").append(MyCsvFileUtil.CSV_DELIMITER);
                }
            }
            lineBuilder.append(MyCsvFileUtil.CSV_TAIL);
        }
        return lineBuilder.toString();
    }

    /**
     * 类转map
     *
     * @param entity 实体
     * @param <T>    泛型
     * @return 返回的map集合
     */
    private static <T> Map<String, Object> toMap(T entity) {
        Class<?> bean = entity.getClass();
        Field[] fields = bean.getDeclaredFields();
        Map<String, Object> map = new TreeMap<>();
        for (Field field : fields) {
            try {
                if (!"serialVersionUID".equals(field.getName())) {
                    String methodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                    Method method = bean.getDeclaredMethod(methodName);
                    Object fieldValue = method.invoke(entity);
                    map.put(field.getName(), fieldValue);
                }
            } catch (Exception e) {
                StaticLog.warn("toMap() Exception={}", e.getMessage());
            }
        }
        return map;
    }
    /**
     * 创建表格行标题 如果有注解 MyExcelName ,则用
     *
     * @param entity 实体
     * @param <T>    实体
     * @return 表头
     */
    private static <T> List<String> resolveExcelTableName(T entity) {
        Class<?> bean = entity.getClass();
        Field[] fields = bean.getDeclaredFields();
        Map<String, String> map = new TreeMap<>();
        for (Field field : fields) {
            try {
                if (!"serialVersionUID".equals(field.getName())) {
                    String tableTitleName = field.getName();
                    MyExcelName myFieldAnn = field.getAnnotation(MyExcelName.class);
                    String annName = myFieldAnn.name();
//                    if (StrUtil.isNotBlank(annName)) {
//                        tableTitleName = annName;
//                    }
                    map.put(tableTitleName,annName);
                }
            } catch (Exception e) {
                StaticLog.warn("toMap() Exception={}", e.getMessage());
            }
        }
        return map.values().stream().toList();
    }
    /**
     * 将文件导出到csv
     *
     * @param list          数据
     * @param path          父级路径
     * @param isShowChinese 表头是否显示中文
     */
    public static String export(List list, String path, boolean isShowChinese) {
        //存放地址&文件名
        String fileName = path + buildCsvFileFileName(list);
        String tableNames = "";
        if (isShowChinese) {
            // 创建表格行标题 注解名 ,可以是中文
            tableNames = buildCsvFileTableNamesNew(resolveExcelTableName(list.get(0)));
        } else {
            // 创建表格行标题 属性名
            tableNames = MyCsvFileUtil.buildCsvFileTableNames(list);
        }
        //创建文件
        writeFile(fileName, tableNames);
        //写入数据
        String contentBody = buildCsvFileBodyMap(list);
        //调用方法生成
        writeFile(fileName, contentBody);
        return fileName;
    }
}

5、测试类

public class Main {
    public static void main(String[] args) {
        District district1 = new District("110101", "东城区", "110100", "北京北京市东城区");
        District district2 = new District("110102", "西城区", "110100", "北京北京市西城区");
        District district3 = new District("110105", "朝阳区", "110100", "北京北京市朝阳区");
        District district4 = new District("110107", "石景山区", "110100", "北京北京市石景山区");
        District district5 = new District("110108", "海淀区", "110100", "北京北京市海淀区");
        District district6 = new District("110109", "门头沟区", "110100", "北京北京市门头沟区");
        District district7 = new District("110111", "房山区", "110100", "北京北京市房山区");
        District district8 = new District("110112", "通州区", "110100", "北京北京市通州区");
        District district9 = new District("110113", "顺义区", "110100", "北京北京市顺义区");
        District district10 = new District("110114", "昌平区", "110100", "北京北京市昌平区");
        District district11 = new District("110115", "大兴区", "110100", "北京北京市大兴区");
        District district12 = new District("110116", "怀柔区", "110100", "北京北京市怀柔区");
        District district13 = new District("110117", "平谷区", "110100", "北京北京市平谷区");
        District district14 = new District("110228", "密云区", "110100", "北京北京市密云区");
        // 类不确定 随便怎么传都行
        List<District> districts = new ArrayList<>();
        districts.add(district1);
        districts.add(district2);
        districts.add(district3);
        districts.add(district4);
        districts.add(district5);
        districts.add(district6);
        districts.add(district7);
        districts.add(district8);
        districts.add(district9);
        districts.add(district10);
        districts.add(district11);
        districts.add(district12);
        districts.add(district13);
        districts.add(district14);
        String fileName = MyCsvFileUtil.export(districts, "d:\\",false);
        MyCsvFileUtil.export(districts, "d:\\",true);
        StaticLog.info("文件导出成功,文件名:{}", fileName);
    }
}

6、效果图

  • 原始表头
    image
  • 中文表头
    image
posted @ 2023-03-04 08:31  his365  阅读(17)  评论(0编辑  收藏  举报