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 name() default "";
}
3、实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class District implements Serializable {
/**
* 地址编码
*/
@MyExcelName(name="编码")
private String code;
/**
* 地址名称
*/
@MyExcelName(name="名称")
private String name;
/**
* 地址父级编码
*/
@MyExcelName(name="父级编码")
private String parentCode;
/**
* 当前地区对应的全称
*/
@MyExcelName(name="全称")
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、效果图
- 原始表头

- 中文表头

java-tocsv的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java 将Excel转为图片、html、XPS、XML、CSV
通过文档格式转换,可满足不同办公场合对文档操作的需求.本文将介绍转换Excel文档为其他常见文档格式的方法.通过文中的方法,可支持将Excel转换为包括PDF.图片.html.XPS.XML.CSV. ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
- Java多线程基础学习(一)
1. 创建线程 1.1 通过构造函数:public Thread(Runnable target, String name){} 或:public Thread(Runnable target ...
随机推荐
- Django框架路由层-无名有名分组-无名有名分组反向解析
目录 一:路由层 1.路由匹配(错误演示) 2.路由匹配错误原因 3.路由匹配(解决方式1) 4.settings配置文件控制自动添加斜杠匹配 5.url方法第一个参数是正则表达式(正规使用url) ...
- python Flask 操作数据库(2)
单表操作 数据准备 from flask import Flask from flask_sqlalchemy import SQLAlchemy class Config: DEBUG = True ...
- P1162填涂颜色——题解
题目描述 由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向.现要求把闭合圈内的所有空间都填写成2.例如:6×6的方阵(n=6),涂色前和涂色后的方阵如下: 0 ...
- SQL中常用函数操作
--在SQL SERVER中批量替换字符串的方法 update [Table] set [Field] = REPLACE([Field],'被替换的原内容','要替换的内容') update HBb ...
- IntelliJ中高效重构的 10 个快捷方式
前言 在日常的开发工作中,我们经常需要重构,重构可以让我们写出的代码更上一层楼.所以,我会借助IntelliJ提供的一些功能,帮助我高效进行重构.这里是我推荐10个快捷方式,也是我每天都在使用的,非常 ...
- docker配置阿里云加速
登录阿里云找到镜像加速 搜索容器镜像服务,进入管理控制台 找到镜像加速器,根据下面配置好即可 centos7.7x64例子 sudo mkdir -p /etc/docker sudo tee /et ...
- Kubernetes(k8s)配置文件管理:ConfigMap
目录 一.系统环境 二.前言 三.ConfigMap概览 四.创建ConfigMap 五.ConfigMap的使用 5.1 以环境变量的方式使用ConfigMap 5.2 以卷的方式使用ConfigM ...
- 使用 NineData 实现备份集的实时查询
使用 NineData 实现备份集的实时查询 背景信息 数据作为一家公司的重要资产,其重要程度不言而喻.数据库为数据提供存取服务,担任着重要的角色,如果因数据误删.服务器故障.病毒入侵等原因导致数据丢 ...
- 【Oculus Interaction SDK】(三)限制可操作物体的移动 / 旋转
前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...
- MySQL8.0 高可用集群化 · mysql-shell · mysql-router · docker · 单主多从
高可用集群的基本特点 负载均衡 / 读写分离 / 故障转移本文以此为目标,利用 mysql-shell.mysql-router,基于 docker 的环境架构(篇幅太长,内容多了点儿). 一.名词及 ...