以上是上传ftp的代码。可以当做工具类使用
需要的参数
String fileName = mehrEmailDto.getLine() + "_ACT_Report_" + yyyyMMddHHmmss + ".xlsx"; InputStream ins = transferIns(workbook); //把excel表格转换成字节IO流 String uploadPath = "ICM\\ACTReport\\" + yyyyMMddHHmmss;
workbook是已经创建好的表格,下面的方法是把表格转换成字节流
/** * 把excel表格转换成字节IO流 * @param workbook * @return */ private InputStream transferIns(Workbook workbook) { try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { workbook.write(bos); byte[] byteArray = bos.toByteArray(); return new ByteArrayInputStream(byteArray); } catch (IOException e) { log.error("Workbook 转 InputStream 失败", e); } return null; }
下面就是ftp上传代码 可以当做工具类使用
package com.luxsan.lpms.ftp;
import com.luxsan.lpms.config.FtpConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* FTP 上传下载,<strong>不带 {@link FTPClient} 参数</strong>的 {@code upload/download} 方法,连接到的是
* <strong>mail-ftp</strong>。如果要上传到其它的 {@code FTP} 服务器,请使用带 {@link FTPClient} 参数的的相应方法。
*
* @author luxsan.ZERO
*/
@Slf4j
@Service
public class FtpService {
public static final String SEPARATOR = "/";
@Resource
private FtpConfig ftpConfig;
@Value("${mail-ftp.ip}")
String ip;
@Value("${mail-ftp.port}")
Integer port;
@Value("${mail-ftp.username}")
String username;
@Value("${mail-ftp.password}")
String password;
/**
* 上传文件
*
* @param ftpClient 连接到 FTP 客户端的对象,建议 {@link #connect(String, int, String, String)}
* @param path 上传到服务器上的路径
* @param filename 文件名称
* @param ins 文件流
* @param closeble 调用结束是否自动关闭连接,只上传一次最好就传 {@code true},多次上传可以传 {@code false} 以使用同一个 {@code FTPClient}
* 实例进行多次操作,但这样必须在调用结束后<strong>手动关闭连接</strong>
*/
public void upload(FTPClient ftpClient, String path, String filename, InputStream ins, boolean closeble) {
if (ftpClient == null) {
throw new RuntimeException("连接失败");
}
String[] paths = separatorTrans(path).split(SEPARATOR);
try {
// 每次都移动到根目录
ftpClient.changeWorkingDirectory("/");
for (String p : paths) {
boolean changed = ftpClient.changeWorkingDirectory(p);
if (!changed) {
ftpClient.makeDirectory(p);
ftpClient.changeWorkingDirectory(p);
}
}
boolean result = ftpClient.storeFile(filename, ins);
if (!result) {
log.warn("Upload failed. filename: {}", path + "/" + filename);
} else {
log.info("Upload completed. filename: {}", path + "/" + filename);
}
if (closeble) {
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
}
} catch (IOException e) {
log.error("上传失败,ip: {} port: {} 文件名: {} 路径: {}", ftpConfig.getIp(), ftpConfig.getPort(),
filename, path, e);
throw new RuntimeException(e);
}
}
/**
* 下载文件
*
* @param ftpClient 连接到 FTP 客户端的对象,建议 {@link #connect(String, int, String, String)}
* @param path 服务器上的文件路径
* @param filename 文件名称
* @param out 输出流
* @param closeble 调用结束是否自动关闭连接,只下载一次最好就传 {@code true},多次下载可以传 {@code false} 以使用同一个 {@code FTPClient}
* 实例进行多次操作,但这样必须在调用结束后<strong>手动关闭连接</strong>
*/
public void download(FTPClient ftpClient, String path, String filename, OutputStream out, boolean closeble) {
if (ftpClient == null) {
throw new RuntimeException("连接失败");
}
try {
ftpClient.changeWorkingDirectory(path);
boolean result = ftpClient.retrieveFile(filename, out);
if (!result) {
log.warn("Download failed. filename: {}", path + "/" + filename);
} else {
log.info("Download completed. filename: {}", path + "/" + filename);
}
if (closeble) {
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
} else {
ftpClient.changeWorkingDirectory("/");
}
} catch (IOException e) {
log.error("下载失败,ip: {} port: {} 路径: {}", ftpConfig.getIp(), ftpConfig.getPort(), path, e);
throw new RuntimeException(e);
}
}
/**
* 上传文件到 <strong>mail-ftp</strong>
*
* @param path 上传到服务器上的路径
* @param fileName 文件名称
* @param ins 文件流
*/
public void upload(String path, String fileName, InputStream ins) {
FTPClient ftpClient = connect(ip, port, username, password);
upload(ftpClient, path, fileName, ins, true);
}
/**
* 从 <strong>mail-ftp</strong> 上下载文件
*
* @param path 文件服务器上的路径
* @param filename 文件名称
* @param out 输出流
*/
public void download(String path, String filename, OutputStream out) {
FTPClient ftpClient = connect(ip, port, username, password);
download(ftpClient, path, filename, out, true);
}
/**
* 获取 FTP 连接
*
* @param ip IP
* @param port 端口
* @param username 用户名
* @param password 密码
* @return FTPClient
*/
public static FTPClient connect(String ip, int port, String username, String password) {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("utf-8");
try {
ftpClient.connect(ip, port);
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
ftpClient.disconnect();
return null;
}
ftpClient.login(username, password);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
} catch (IOException e) {
log.error("连接失败,ip: {} port: {}", ip, port, e);
return null;
}
return ftpClient;
}
/**
* 反斜杠转为正斜杠
*
* @param str string
* @return string
*/
public static String separatorTrans(String str) {
return str.replaceAll("\\\\", SEPARATOR);
}
/**
* Workbook 转 InputStream
*
* @param workbook Workbook
* @return InputStream
*/
public static InputStream workbookToInputStream(Workbook workbook) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
byte[] byteArray = bos.toByteArray();
return new ByteArrayInputStream(byteArray);
} catch (IOException e) {
log.error("Workbook 转 InputStream 失败", e);
}
return null;
}
/* 日期-时间 工具方法 */
private static final DateTimeFormatter DATE_NO_SYMBOL = DateTimeFormatter.ofPattern("yyyyMMdd");
private static final DateTimeFormatter DATE_TIME_NO_SYMBOL = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
private static final DateTimeFormatter DATE_TIME_DEFAULT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 获取当前时间 yyyyMMdd 格式的字符串
*
* @return str
*/
public static String dateNowNoSymbolStr() {
return LocalDate.now().format(DATE_NO_SYMBOL);
}
/**
* 获取当前时间 yyyyMMddHHmmss 格式的字符串
*
* @return str
*/
public static String dateTimeNowNoSymbolStr() {
return LocalDateTime.now().format(DATE_TIME_NO_SYMBOL);
}
/**
* 获取当前时间 yyyy-MM-dd HH:mm:ss 格式的字符串
*
* @return str
*/
public static String dateTimeNowDefaultStr() {
return LocalDateTime.now().format(DATE_TIME_DEFAULT);
}
}