<
groupId
>
org.apache.commons
</
groupId
>
<
artifactId
>
commons-csv
</
artifactId
>
<
version
>
1.7
</
version
>
</
dependency
>
我把CSV的上传、下载、解析、写入的通用方法,都整合在了CSVUtils类中。
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
* @Author: Denebola
* @Date: 2019/7/18-16:48
* @Description: CSV工具类
public class CSVUtils {
private static Logger logger = LoggerFactory.getLogger(CSVUtils.class);
private final static String NEW_LINE_SEPARATOR = "\n";
private final static URL PATH = Thread.currentThread().getContextClassLoader().getResource("");
* @return File
* @Description 创建CSV文件
* @Param fileName 文件名,head 表头,values 表体
public static File makeTempCSV(String fileName, String[] head, List<String[]> values) throws IOException {
File file = File.createTempFile(fileName, ".csv", new File(PATH.getPath()));
CSVFormat formator = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
BufferedWriter bufferedWriter =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
CSVPrinter printer = new CSVPrinter(bufferedWriter, formator);
printer.printRecord(head);
for (String[] value : values) {
printer.printRecord(value);
printer.close();
bufferedWriter.close();
return file;
* @return boolean
* @Description 下载文件
* @Param response,file
public static boolean downloadFile(HttpServletResponse response, File file) {
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
OutputStream os = null;
try {
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
os = response.getOutputStream();
os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
byte[] buffer = new byte[1024];
int i = bufferedInputStream.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bufferedInputStream.read(buffer);
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
if (bufferedInputStream != null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
if (fileInputStream != null) {
try {
fileInputStream.close();
}
catch (IOException e) {
e.printStackTrace();
file.delete();
return false;
* @return File
* @Description 上传文件
* @Param multipartFile
public static File uploadFile(MultipartFile multipartFile) {
String path = PATH.getPath() + multipartFile.getOriginalFilename();
try {
File file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
multipartFile.transferTo(file);
logger.info("上传文件成功,文件名===>" + multipartFile.getOriginalFilename() + ", 路径===>" + file.getPath());
return file;
} catch (IOException e) {
logger.error("上传文件失败" + e.getMessage(), e);
return null;
* @return List<List<String>>
* @Description 读取CSV文件的内容(不含表头)
* @Param filePath 文件存储路径,colNum 列数
public static List<List<String>> readCSV(String filePath, int colNum) {
BufferedReader bufferedReader = null;
InputStreamReader inputStreamReader = null;
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
inputStreamReader = new InputStreamReader(fileInputStream);
bufferedReader = new BufferedReader(inputStreamReader);
CSVParser parser = CSVFormat.DEFAULT.parse(bufferedReader);
List<List<String>> values = new ArrayList<>();
int rowIndex = 0;
for (CSVRecord record : parser.getRecords()) {
if (rowIndex == 0) {
rowIndex++;
continue;
List<String> value = new ArrayList<>(colNum + 1);
for (int i = 0; i < colNum; i++) {
value.add(record.get(i));
values.add(value);
rowIndex++;
return values;
} catch (IOException e) {
logger.error("解析CSV内容失败" + e.getMessage(), e);
}finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
Controller.java
import com.denebola.learnspringboot.CSVUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.List;
@Slf4j
@RestController
public class Controller {
private static Logger logger = LoggerFactory.getLogger(Controller.class);
@Autowired
private Service service;
* @param response
* @return
* @Description 下载CSV
@GetMapping("/downloadAll")
public String downloadAllUserRoleCSV(HttpServletResponse response) {
String[] head = service.getHead();
List<String[]> values = service.getValues();
String fileName = service.getName();
File file = CSVUtils.makeTempCSV(fileName, head, values);
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName +".csv");
CSVUtils.downloadFile(response, file);
return null;
* @return
* @Description 上传CSV
* @Param file
@PostMapping(value = "/upload")
public String upload(@RequestParam("file") MultipartFile multipartFile) {
try {
if (multipartFile.isEmpty()) {
return "500";
File file = CSVUtils.uploadFile(multipartFile);
List<List<String>> userRoleLists = CSVUtils.readCSV(file.getPath(), 2);
service.doSth(userRoleLists);
file.delete();
return "200";
} catch (Exception e) {
e.printStackTrace();
return "500";
需要值得注意的是,在使用Java生成CSV文件时,可能出现中文乱码的问题,这是由于微软的产品为了检测一个字节流是否是UTF-8编码,而添加了BOM标记。而有的文本编辑软件,比如Notepad、VScode、记事本等,不会做这种检测,会当作正常字符处理。所以产生的现象就是,Excel打开是乱码时,记事本打开不是乱码。
为了解决这种问题,我们可以手动的加入BOM。上述代码中添加的方式是os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});,如果不使用Response的out进行输出的话,可以改用以下代码:
OutputStreamWriter osw = new OutputStreamWriter(resp.getOutputStream(), "UTF-8");
osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF }));
工作中遇到了将所有数据整合成CSV文件并下载、上传CSV文件并解析,这两个需求。现在把处理方法记录下来,作为总结。项目构建jar包引入CSV的解析和写入使用到的是commons-csv的包,pom中的定义如下 <dependency> <groupId>org.apache.commons</groupId> ...
赠送jar包:seata-spring-boot-starter-1.3.0.jar;
赠送原API文档:seata-spring-boot-starter-1.3.0-javadoc.jar;
赠送源代码:seata-spring-boot-starter-1.3.0-sources.jar;
赠送Maven依赖信息文件:seata-spring-boot-starter-1.3.0.pom;
包含翻译后的API文档:seata-spring-boot-starter-1.3.0-javadoc-API文档-中文(简体)版.zip;
Maven坐标:io.seata:seata-spring-boot-starter:1.3.0;
标签:seata、spring、boot、starter、中文文档、jar包、java;
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。
人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
支持TCP长连接消息转发到Spring容器
支持自定义消息枚举类( CommandController , CommandMapping )
支持自定义通信协议解析( ProtocolProcessor )
支持不同系统事件通知机制( EventHandler )
使用SpringMVC中RestController的CommandController和GetMapping的CommandMapping进行消息定义,系统会自动将其注册进系统里
@CommandController
public class SimpleCommand {
@Autowired
private SimpleService simpleService;
@Comm
< dependency>
< groupId>org.springframework.boot</ groupId>
< artifactId>spring-boot-starter-web</ artifactId>
< version>${spring-boot.version}</ version>
</ dependency>
spring-boot-project依赖根
spring-boot-first-application-sample演示模块
spring-boot-configuration-sample配置模块
spring-boot-import-sample导入实现模块
spring-boot-alias-annotation-sample注解属性别名模块
spring-boot-actuator-sample监控组件模块
spring-boot-enable-sample自动装配模块
formatter-spring-boot-starter-sample自定义启动模
.csv文件是什么?
CSV文件最早用在简单的数据库里,由于其格式简单,并具备很强的开放性,所以起初被扫图家用作自己图集的标记。CSV文件是个纯文本文件,每一行表示一张图片的许多属性。你在收一套图集时,只要能找到它的CSV文件,用专用的软件校验后,你对该图集的状况就可以了如指掌。 每行相当于一条记录,是用“,”分割字段的纯文本数据库文件
在 java中解析 来吧上代码吧
maven
<dependency>
<groupId>de.sieg
EasyExcel
EasyExcel是一个基于Java的简单,省内存的读写Excel的开源项目。在节省存储的情况下下支持读写百M的Excel。64M内存1分钟内读取75M(46W行25列)的Excel。 ,当然还有急速模式能恢复,但是内存占用会在100M多一点
Spring Boot Stater依赖
方便在web环境下使用easyexcel ,已上传至maven仓库
< dependency>
< groupId>com.pig4cloud.excel</ groupId>
< artifactId>excel-spring-boot-starter</ arti
交易留言:
在框架中,对事务消息的操作越来越简单。 您只能通过注释来完成交易消息。
无论是事务消息,分布式事务解决方案还是跨平台语言解决方案,事务解决方案的核心问题是确保可以发送消息,并且消费者可以使用它们。
可靠性保证
1.添加@TransactionMessage批注,内核保证,本地事务错误,不发送消息,正确执行,发送消息,即默认提交。
2.默认情况下采用可靠性保证,并核对默认提交。 原因来自先前的因素,该因素保证本地交易不会出错。
<!-- Adding dependencies to pom. XML -->
csv文件默认编码为ANSI,这里出现乱码主要是编码不一致问题
DataInputStream in = new DataInputStream(new FileInputStream(new File("d:\\*.csv")));
BufferedReader br= new BufferedReader(new InputStreamReader(in,"GBK"));//这里如果csv
<!-- https://mvnrepository.com/artifact/com.opencsv/opencsv -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.6</ver
mybatis-spring-boot-starter 和 spring-boot-starter-jdbc 是用于在 Spring Boot 项目中连接数据库的两个依赖包。它们有不同的功能和用途。
mybatis-spring-boot-starter 是 MyBatis 官方提供的一个 Spring Boot Starter,它包含了使用 MyBatis 进行数据库访问所需的所有依赖。通过引入 mybatis-spring-boot-starter,您可以方便地使用 MyBatis 进行数据库操作,而无需单独引入 spring-boot-starter-jdbc 。
spring-boot-starter-jdbc 是 Spring Boot 官方提供的一个 Starter,用于支持使用 JDBC 进行数据库访问。如果您不使用 MyBatis,而只是使用 Spring 的 JdbcTemplate 进行数据库操作,那么您需要引入 spring-boot-starter-jdbc 依赖。它提供了一些必要的配置和支持,使您可以方便地使用 JDBC 进行数据库访问 。
引用的内容中提到,如果您已经引入了 mybatis-spring-boot-starter,那么您不再需要单独引入 spring-boot-starter-jdbc。这是因为 mybatis-spring-boot-starter 已经包含了 spring-boot-starter-jdbc 的依赖。这样,您就可以直接使用 MyBatis 进行数据库操作,而无需关注底层的 JDBC 配置 。
总结起来,mybatis-spring-boot-starter 是用于集成 MyBatis 的 Spring Boot Starter,而 spring-boot-starter-jdbc 是用于支持使用 JDBC 进行数据库操作的 Spring Boot Starter。如果您使用 MyBatis,建议直接引入 mybatis-spring-boot-starter,它已经包含了必要的 JDBC 依赖。如果您只是使用 Spring 的 JdbcTemplate,那么需要引入 spring-boot-starter-jdbc 。