背景:接着上一篇下载文件,从ftp
下载到csv
文件后,解析转换成想要的数据存储数据库,此处设计成用easyexcel
读取csv
中的数据,并转换成自己想要的格式,这里选easyexcel
的原因就是因为简单
,下面将逐步解释如何使用以及在使用中需要注意的事项。
引入依赖
<!--easyExcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.2</version>
</dependency>
<!--zip操作-->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.0</version>
</dependency>
检查文件是否存在
listFiles
是上一篇的方法
sourceOpt
为真代表存在
List<String> files = sftpHelper.listFiles(sftpPathAll);
Optional<String> sourceOpt = files.stream().filter(f -> f.equals(fileName)).findFirst();
下载文件
downloadFile
是上一篇的方法
sftpHelper.downloadFile(sftpPathAll, fileName, savePathAll);
解压文件
unZip
方法是解压操作
package x.x.infra.util;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import lombok.extern.slf4j.Slf4j;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
@Slf4j
public class ZipFileUtils {
private static int bufferSize = 2048;
/**
* 解压到指定目录
*/
public static void unZip(String zipPath, String descDir) throws IOException {
unZip(new File(zipPath), descDir);
}
/**
* 解压文件到指定目录
*/
@SuppressWarnings("rawtypes")
public static void unZip(File zipFile, String descDir) throws IOException {
File pathFile = new File(descDir);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
//解决zip文件中有中文目录或者中文文件
// ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
ZipFile zip = new ZipFile(zipFile);
for (Enumeration entries = zip.getEntries(); entries.hasMoreElements(); ) {
ZipEntry entry = (ZipEntry) entries.nextElement();
String zipEntryName = entry.getName();
InputStream in = zip.getInputStream(entry);
String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
//判断路径是否存在,不存在则创建文件路径
File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
if (!file.exists()) {
file.mkdirs();
}
//判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
if (new File(outPath).isDirectory()) {
continue;
}
log.info("解压文件路径:"+outPath);
OutputStream out = new FileOutputStream(outPath);
byte[] buf1 = new byte[1024];
int len;
while ((len = in.read(buf1)) > 0) {
out.write(buf1, 0, len);
}
in.close();
out.close();
}
}
/**
* 压缩
* @param srcFileOrDir 原文件或文件夹
* @param destZipFilePath 输出到的目标路径,默认zip文件为原文件或文件夹名称
*/
public static boolean zip(String srcFileOrDir, String destZipFilePath){
File file = new File(srcFileOrDir);
if(!file.exists()){
return false;
}
String destZipFileName = file.getName();
return zip(srcFileOrDir, destZipFilePath, destZipFileName);
}
/**
* 压缩
* @param srcFileOrDir 原文件或文件夹
* @param destZipFilePath 输出到的目标路径
* @param destZipFileName 生成的zip文件名称
*/
public static boolean zip(String srcFileOrDir, String destZipFilePath, String destZipFileName){
File file = new File(srcFileOrDir);
if(!file.exists()){
// logger.info("原文件或文件夹不存在。");
return false;
}
if(!destZipFilePath.endsWith(File.separator)){
destZipFilePath += File.separator;
}
File destZipFileParentDir = new File(destZipFilePath);
if(!destZipFileParentDir.exists()){
destZipFileParentDir.mkdirs();
}
if(!destZipFileName.endsWith(".zip")&&!destZipFileName.endsWith(".ZIP")){
destZipFileName += ".zip";
}
boolean zipResult = false;
if(file.isFile()){
zipResult = zipFile(srcFileOrDir, destZipFilePath, destZipFileName);
}else if(file.isDirectory()){
zipResult = zipDir(srcFileOrDir, destZipFilePath, destZipFileName);
}
// logger.info("["+srcFileOrDir+"]-->["+destZipFilePath + destZipFileName+"]压缩结果:["+zipResult+"]");
return zipResult;
}
private static boolean zipFile(String srcFileName, String destZipFilePath, String destZipFileName){
boolean zipResult = false;
File srcFile = new File(srcFileName);
ZipOutputStream zipOutputStream = null;
try {
zipOutputStream = new ZipOutputStream(new FileOutputStream(destZipFilePath + destZipFileName));
zipOutputStream.setEncoding(System.getProperty("sun.jnu.encoding"));
String fileName = srcFile.getName();
ZipEntry entry = new ZipEntry(fileName);
BufferedInputStream bis = null;
try {
zipOutputStream.putNextEntry(entry);
bis = new BufferedInputStream(new FileInputStream(srcFile));
byte[] buf = new byte[bufferSize];
int len;
while ((len = bis.read(buf)) >= 0) {
zipOutputStream.flush();
zipOutputStream.write(buf, 0, len);
}
zipResult = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(zipOutputStream!=null){
zipOutputStream.closeEntry();
}
if(bis!=null){
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if(zipOutputStream!=null){
zipOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return zipResult;
}
private static boolean zipDir(String srcDir, String destZipFilePath, String destZipFileName){
boolean zipResult = false;
if(!srcDir.endsWith(File.separator)){
srcDir += File.separator;
}
File srcFile = new File(srcDir);
File[] files = srcFile.listFiles();
ZipOutputStream zipOutputStream = null;
try {
zipOutputStream = new ZipOutputStream(new FileOutputStream(destZipFilePath + destZipFileName));
zipOutputStream.setEncoding(System.getProperty("sun.jnu.encoding"));
if(files!=null&&files.length>0){
for(File f :files){
compressFiles(f, f.getParent() ,zipOutputStream);
}
}
zipResult = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if(zipOutputStream!=null){
zipOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return zipResult;
}
private static void compressFiles(File file, String basePath, ZipOutputStream stream){
if(file==null||stream==null){
return;
}
if(file.isDirectory()){
ZipEntry entry = new ZipEntry(getEntryPath(file,basePath) + File.separator);
try {
stream.putNextEntry(entry);
} catch (IOException e) {
e.printStackTrace();
}
File[] files = file.listFiles();
if(files!=null&&files.length>0){
for(File f :files){
compressFiles(f, basePath, stream);
}
}
}else{
String fileName = getEntryPath(file, basePath);
ZipEntry entry = new ZipEntry(fileName);
BufferedInputStream bis = null;
try {
stream.putNextEntry(entry);
bis = new BufferedInputStream(new FileInputStream(file));
byte[] buf = new byte[bufferSize];
int len;
while ((len = bis.read(buf)) >= 0) {
stream.flush();
stream.write(buf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(stream!=null){
stream.closeEntry();
}
if(bis!=null){
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static String getEntryPath(File file, String basePath){
String path = file.getPath().substring(basePath.length() + 1);
return path;
}
}
定义非数据库对象
复制一份已有的数据库对象,加个VO
后缀代表是非数据库对象,修改此VO
结尾的对象的字段属性全部为string
,因为在easyexcel
转换对象映射的时候会默认转成string
类型。@ExcelProperty
此注解定义和csv
文件列的关系。这里注意那些没用的属性不要出现
在此映射类中。
@Getter
@Setter
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class GlDetailLineItfVo {
@ExcelProperty(index = 0)
private String name;
}
读取文件封装成想要的对象
invoke
此方法第一个形参是读取到csv
文件中的数据,在这里可以操作那些对象映射不上的数据转换,比如日期类型
、BigDecimal
类型等,然后存入一个list
中,返回出来给外面的方法用。charset
设置中文乱码问题,excelType
设置读取文件格式,sheet
设置读取第几个页,headRowNumber
设置从第几行开始读默认是第二行。
public List<Itf> getObjFromCsv(Map<String, String> map) {
Optional.ofNullable(map.get("filePath")).orElseThrow(() -> new CommonException("文件路径不能为空"));
File file = new File(map.get("filePath"));
InputStream is = null;
List<Itf> itfList = new ArrayList<>();
try {
//获取输入流
is = new FileInputStream(file);
EasyExcel.read(is, itfVo.class, new ReadListener<itfVo>() {
@Override
public void invoke(itfVo data, AnalysisContext context) {
Integer row = context.readRowHolder().getRowIndex();
System.out.println("第几行数据:"+row);
//把解析到的每一行数据都存入list中
Itf itf= new Itf();
BeanUtils.copyProperties(data,itf);
//手动转换对象不一致的属性
} catch (ParseException e) {
throw new RuntimeException(e);
}
itfList .add(itf);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("最后一次走这里");
//这里可以写操作数据库,我没写,我的操作数据库是另外一个方法
}
}).charset(Charset.forName("GBK"))//中文乱码
.excelType(ExcelTypeEnum.CSV)//文件格式
.sheet(0)//读取第一个sheet
.headRowNumber(1)//从数据的第2行开始读
.doRead();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
is.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return itfList ;
}
至此下载文件,解压,解析已经完成