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 ...
随机推荐
- 安装aio-pika报错
报错内容: WARNING: You are using pip version 21.1.2; however, version 21.3.1 is available. You should co ...
- Maven多模块管理
项目的目录结构: 一.创建父工程的必须遵循以下两点: 1.packaging标签的文本内容必须设置为pom 1 <?xml version="1.0" encoding=&q ...
- 详解JAVA线程问题诊断工具Thread Dump
摘要:Thread Dump是非常有用的诊断Java应用问题的工具. 本文分享自华为云社区<调试排错 - Java 线程分析之线程Dump分析>,作者:龙哥手记. Thread Dump是 ...
- css预处理器scss/sass语法以及使用
scss scss在css基础语法上面增加了变量 (variables).嵌套 (nested rules).混合 (mixins).导入 (inline imports) 等高级功能,使用scss可 ...
- 内网渗透-at&schtasks&impacket的使用
内网机器结构 机器账号密码如下: 2008 r2 webserver 域内 web 服务器 本地管理员账号密码 : .\administraotr:admin!@#45 当前机器域用户密码 : god ...
- 买不到的数目【第四届蓝桥杯省赛C++A组,第四届蓝桥杯省赛JAVAC组】
买不到的数目 小明开了一家糖果店. 他别出心裁:把水果糖包成4颗一包和7颗一包的两种. 糖果不能拆包卖. 小朋友来买糖的时候,他就用这两种包装来组合. 当然有些糖果数目是无法组合出来的,比如要买 10 ...
- 商城网站商品sku选择的js简易实现
商城网站商品sku选择的js简易实现 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta c ...
- SEO关键词布局方法
关键词在<title>标签. description属性. keywords属性中是如何布局的. 1.<title>标签中布局关键词 <title>标签是用来定义网 ...
- 问题记录:VMware vSphere vCenter 7.0 上传文件失败
问题记录:VMware vSphere vCenter 7.0 上传文件失败 环境说明: VC版本:VMware vSphere vCenter 7.0 ESXi版本:VMware vSphere E ...
- (数据科学学习手札149)用matplotlib轻松绘制漂亮的表格
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,matplotlib作为数据可 ...