FtpFileUtil.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. package com.steerinfo.dil.util;
  2. import com.steerinfo.framework.utils.io.IOUtils;
  3. import com.steerinfo.framework.utils.text.Charsets;
  4. import org.apache.commons.net.ftp.*;
  5. import org.springframework.stereotype.Component;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.*;
  8. import java.util.Base64;
  9. /**
  10. * POIExcelToHtml 文件转换:
  11. *
  12. * @author generator
  13. * @version 1.0-SNAPSHOT 2021-08-09 18:06
  14. * 类描述
  15. * 修订历史:
  16. * 日期:2021-08-09
  17. * 作者:shadow
  18. * 参考:
  19. * 描述:
  20. * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
  21. * @see null
  22. */
  23. @Component
  24. public class FtpFileUtil {
  25. /**
  26. * ftp服务器ip地址
  27. */
  28. // String FTP_ADDRESS;
  29. private String FTP_ADDRESS = "172.16.90.238";
  30. /**
  31. * 端口号
  32. */
  33. //Integer FTP_PORT;
  34. private Integer FTP_PORT = 21;
  35. /**
  36. * 用户名
  37. */
  38. private String FTP_USERNAME = "ftptest";
  39. /**
  40. * 密码
  41. */
  42. private String FTP_PASSWORD = "at286315";
  43. private FTPClient ftpClient = new FTPClient();
  44. private static final String SPOT = ".";
  45. /**
  46. * 上传文件
  47. *
  48. * @param filePath 文件路径
  49. * @param filename 文件名称
  50. * @param basePath 上级目录
  51. * @param inputStream 文件输入流
  52. * @return 是否成功
  53. */
  54. public boolean uploadFile(String filePath, String filename, String basePath, InputStream inputStream) {
  55. boolean result = false;
  56. try {
  57. // 连接FTP服务器
  58. ftpClient.connect(FTP_ADDRESS, FTP_PORT);
  59. ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
  60. int reply;
  61. ftpClient.enterLocalPassiveMode();
  62. reply = ftpClient.getReplyCode();
  63. if (!FTPReply.isPositiveCompletion(reply)) {
  64. ftpClient.disconnect();
  65. return false;
  66. }
  67. //切换到上传目录
  68. boolean changed = ftpClient.changeWorkingDirectory(filePath);
  69. if (!changed) {
  70. //如果目录不存在创建目录
  71. String[] dirs = filePath.split("/");
  72. String tempPath = basePath;
  73. for (String dir : dirs) {
  74. if (null == dir || "".equals(dir)) {
  75. continue;
  76. }
  77. tempPath += "/" + dir;
  78. if (!ftpClient.makeDirectory(tempPath)) {
  79. return false;
  80. } else {
  81. ftpClient.changeWorkingDirectory(tempPath);
  82. }
  83. }
  84. }
  85. System.out.println("当前目录" + ftpClient.printWorkingDirectory());
  86. //设置为被动模式
  87. //设置上传文件的类型为二进制类型
  88. ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  89. //上传文件
  90. if (!ftpClient.storeFile(filename, inputStream)) {
  91. System.out.println("上传文件失败");
  92. return false;
  93. }
  94. ftpClient.logout();
  95. result = true;
  96. } catch (IOException e) {
  97. e.printStackTrace();
  98. } finally {
  99. if (ftpClient.isConnected()) {
  100. try {
  101. inputStream.close();
  102. ftpClient.disconnect();
  103. } catch (IOException ioe) {
  104. ioe.printStackTrace();
  105. }
  106. }
  107. }
  108. return result;
  109. }
  110. /***
  111. * 上传
  112. * @param buffIn 文件流
  113. * @param filePath 文件路径
  114. * @param fileName 文件名称
  115. * @param needDelete 是否删除
  116. * @return 是否成功
  117. * @throws FTPConnectionClosedException ftp错误
  118. * @throws IOException io流错误
  119. * @throws Exception 普通错误
  120. */
  121. public boolean uploadToFtp(InputStream buffIn, String filePath, String fileName, boolean needDelete)
  122. throws FTPConnectionClosedException, IOException, Exception {
  123. boolean result;
  124. try {
  125. //建立连接
  126. this.connectToServer();
  127. ftpClient.changeWorkingDirectory("/");
  128. this.setFileType(FTP.BINARY_FILE_TYPE);
  129. int reply = ftpClient.getReplyCode();
  130. if (!FTPReply.isPositiveCompletion(reply)) {
  131. ftpClient.disconnect();
  132. throw new IOException("failed to connect to the FTP Server:" + FTP_ADDRESS);
  133. }
  134. //进入文件目录
  135. boolean changeWork = ftpClient.changeWorkingDirectory(filePath);
  136. if (!changeWork) {
  137. if (!createDirectory(filePath)) {
  138. return false;
  139. }
  140. }
  141. result = ftpClient.storeFile(fileName, buffIn);
  142. if (needDelete) {
  143. ftpClient.deleteFile(fileName);
  144. }
  145. // 输出操作结果信息
  146. if (result) {
  147. System.out.println("uploadToFtp INFO: upload file to ftp : succeed!");
  148. } else {
  149. System.out.println("uploadToFtp INFO: upload file to ftp : failed!");
  150. }
  151. } catch (FTPConnectionClosedException e) {
  152. System.out.println("ftp连接被关闭!");
  153. throw e;
  154. } catch (Exception e) {
  155. System.out.println("ERR : upload file to ftp : failed! ");
  156. throw e;
  157. } finally {
  158. try {
  159. if (buffIn != null) {
  160. buffIn.close();
  161. }
  162. } catch (Exception e) {
  163. System.out.println("ftp关闭输入流时失败!");
  164. }
  165. if (ftpClient.isConnected()) {
  166. closeConnect();
  167. }
  168. }
  169. return result;
  170. }
  171. /***
  172. * 预览
  173. * @param fileName 文件名
  174. * @param filePath 文件路径
  175. * @return 返回HTML
  176. * @throws IOException io流错误
  177. */
  178. public String downloadFile(String fileName, String filePath) throws IOException {
  179. InputStream inputStream;
  180. String data = fileName + "预览失败";
  181. String workhtml = null;
  182. File temp = File.createTempFile("temp", ".temp");
  183. try {
  184. this.connectToServer();
  185. // 设置传输二进制文件
  186. this.setFileType(FTP.BINARY_FILE_TYPE);
  187. ftpClient.enterLocalPassiveMode();
  188. int reply = ftpClient.getReplyCode();
  189. if (!FTPReply.isPositiveCompletion(reply)) {
  190. ftpClient.disconnect();
  191. throw new IOException("failed to connect to the FTP Server:" + FTP_ADDRESS);
  192. }
  193. String directory = filePath.substring(0, filePath.lastIndexOf("/") + 1);
  194. // 进入文件所在目录,注意编码格式,以能够正确识别中文目录
  195. boolean cdStatus = ftpClient.changeWorkingDirectory(directory);
  196. if (!cdStatus) {
  197. return data;
  198. }
  199. String file = filePath.substring(filePath.lastIndexOf("/") + 1);
  200. // 检验文件是否存在
  201. inputStream = ftpClient.retrieveFileStream(file);
  202. String suffixName;
  203. if (inputStream != null) {
  204. if (fileName != null && fileName.contains(SPOT)) {
  205. POIWordToHtml poiWordToHtml = new POIWordToHtml();
  206. suffixName = fileName.substring(fileName.indexOf(".") + 1);
  207. switch (suffixName) {
  208. case "docx":
  209. data = poiWordToHtml.readWordImgToHtml(inputStream);
  210. break;
  211. case "doc":
  212. data = poiWordToHtml.docToHtml(inputStream);
  213. break;
  214. case "xlsx":
  215. case "xls":
  216. data = POIExcelToHtml.excelToHtml(inputStream);
  217. break;
  218. case "pptx":
  219. case "ppt":
  220. data = POIPptToHtml.pptToHtml(inputStream, suffixName);
  221. break;
  222. case "jpg":
  223. case "gif":
  224. case "png":
  225. case "jpeg":
  226. case "jpe":
  227. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  228. IOUtils.copy(inputStream, stream);
  229. String imgStr = Base64.getEncoder().encodeToString(stream.toByteArray());
  230. data = "<img style='width:100%' src=" + "\"data:image/" + suffixName + ";base64," + imgStr + "\"" + "/>";
  231. stream.close();
  232. break;
  233. case "txt":
  234. ByteArrayOutputStream txtStream = new ByteArrayOutputStream();
  235. IOUtils.copy(inputStream, txtStream);
  236. data = txtStream.toString();
  237. break;
  238. default:
  239. data = fileName + "文件暂时不支持预览。";
  240. break;
  241. }
  242. }
  243. inputStream.close();
  244. ftpClient.completePendingCommand();
  245. }
  246. } catch (FTPConnectionClosedException e) {
  247. System.out.println("ftp连接被关闭!");
  248. throw e;
  249. } catch (Exception e) {
  250. System.out.println("ERR : upload file " + fileName + " from ftp : failed!" + e.getMessage());
  251. } finally {
  252. if (ftpClient.isConnected()) {
  253. closeConnect();
  254. }
  255. }
  256. return data;
  257. }
  258. /**
  259. * 下载
  260. *
  261. * @param response 响应头
  262. * @param fileName 文件名
  263. * @param filePath 文件路径
  264. * @return 返回下载是否成功
  265. */
  266. public boolean download(HttpServletResponse response, String fileName, String filePath) {
  267. boolean flag = false;
  268. try {
  269. this.connectToServer();
  270. // 设置传输二进制文件
  271. this.setFileType(FTP.BINARY_FILE_TYPE);
  272. this.ftpClient.enterLocalPassiveMode();
  273. int reply = ftpClient.getReplyCode();
  274. if (!FTPReply.isPositiveCompletion(reply)) {
  275. ftpClient.disconnect();
  276. throw new IOException("failed to connect to the FTP Server:" + FTP_ADDRESS);
  277. }
  278. String transferName = new String(fileName.getBytes(Charsets.UTF_8), Charsets.ISO_8859_1);
  279. String directory = filePath.substring(0, filePath.lastIndexOf("/") + 1);
  280. String file = filePath.substring(filePath.lastIndexOf("/") + 1);
  281. // 进入文件所在目录,注意编码格式,以能够正确识别中文目录
  282. ftpClient.changeWorkingDirectory(directory);
  283. response.setCharacterEncoding("UTF-8");
  284. response.setContentType("multipart/form-data;charset=UTF-8");
  285. response.setHeader("Content-Disposition", "attachment; filename=\"" + transferName + "\"");
  286. FTPFile[] fs = ftpClient.listFiles();
  287. for (FTPFile ff : fs) {
  288. if (ff.getName().equals(file)) {
  289. OutputStream os = response.getOutputStream();
  290. flag = ftpClient.retrieveFile(ff.getName(), os);
  291. os.flush();
  292. os.close();
  293. break;
  294. }
  295. }
  296. closeConnect();
  297. } catch (FTPConnectionClosedException ignored) {
  298. } catch (Exception e) {
  299. e.printStackTrace();
  300. }
  301. return flag;
  302. }
  303. /**
  304. * 下载返回流
  305. *
  306. * @param fileName 文件名称
  307. * @param filePath 文件路径
  308. * @return 返回是否成功
  309. */
  310. public ByteArrayOutputStream download(String fileName, String filePath) {
  311. ByteArrayOutputStream os = new ByteArrayOutputStream();
  312. try {
  313. this.connectToServer();
  314. // 设置传输二进制文件
  315. this.setFileType(FTP.BINARY_FILE_TYPE);
  316. ftpClient.enterLocalPassiveMode();
  317. int reply = ftpClient.getReplyCode();
  318. if (!FTPReply.isPositiveCompletion(reply)) {
  319. ftpClient.disconnect();
  320. throw new IOException("failed to connect to the FTP Server:" + FTP_ADDRESS);
  321. }
  322. String directory = filePath.substring(0, filePath.lastIndexOf("/") + 1);
  323. String file = filePath.substring(filePath.lastIndexOf("/") + 1);
  324. // 进入文件所在目录,注意编码格式,以能够正确识别中文目录
  325. ftpClient.changeWorkingDirectory(directory);
  326. FTPFile[] fs = ftpClient.listFiles();
  327. for (FTPFile ff : fs) {
  328. if (ff.getName().equals(file)) {
  329. os.close();
  330. break;
  331. }
  332. }
  333. closeConnect();
  334. } catch (FTPConnectionClosedException ignored) {
  335. } catch (Exception e) {
  336. e.printStackTrace();
  337. }
  338. return os;
  339. }
  340. public boolean deleteFile(String filePath) throws Exception {
  341. boolean result;
  342. try {
  343. //建立连接
  344. this.connectToServer();
  345. ftpClient.changeWorkingDirectory("/");
  346. this.setFileType(FTP.BINARY_FILE_TYPE);
  347. int reply = ftpClient.getReplyCode();
  348. if (!FTPReply.isPositiveCompletion(reply)) {
  349. ftpClient.disconnect();
  350. throw new IOException("failed to connect to the FTP Server:" + FTP_ADDRESS);
  351. }
  352. String directory = filePath.substring(0, filePath.lastIndexOf("/") + 1);
  353. String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
  354. //进入文件目录
  355. boolean changeWork = ftpClient.changeWorkingDirectory(directory);
  356. if (!changeWork) {
  357. return false;
  358. }
  359. result = ftpClient.deleteFile(fileName);
  360. } catch (FTPConnectionClosedException e) {
  361. System.out.println("ftp连接被关闭!");
  362. throw e;
  363. } catch (Exception e) {
  364. System.out.println("ERR : delete file to ftp : failed! ");
  365. throw e;
  366. } finally {
  367. if (ftpClient.isConnected()) {
  368. closeConnect();
  369. }
  370. }
  371. return result;
  372. }
  373. /***
  374. * 建立连接
  375. * @throws FTPConnectionClosedException ftp错误
  376. * @throws Exception 普通错误
  377. */
  378. private void connectToServer() throws FTPConnectionClosedException, Exception {
  379. if (!ftpClient.isConnected()) {
  380. int reply;
  381. try {
  382. //建立连接
  383. ftpClient = new FTPClient();
  384. //ftpClient.setControlEncoding("GBK");//windows default服务器gbk
  385. ftpClient.setControlEncoding("UTF-8");//linux default UTF-8
  386. ftpClient.connect(FTP_ADDRESS, FTP_PORT);
  387. ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
  388. ftpClient.enterLocalPassiveMode();
  389. reply = ftpClient.getReplyCode();
  390. if (!FTPReply.isPositiveCompletion(reply)) {
  391. ftpClient.disconnect();
  392. System.out.println("connectToServer FTP server refused connection.");
  393. }
  394. } catch (FTPConnectionClosedException ex) {
  395. System.out.println("没有连接数!there are too many connected users,please try later");
  396. throw ex;
  397. } catch (Exception e) {
  398. System.out.println("登录ftp服务器失败");
  399. throw e;
  400. }
  401. }
  402. }
  403. /**
  404. * 设置传输文件类型
  405. *
  406. * @param fileType 文件类型
  407. */
  408. private void setFileType(int fileType) {
  409. try {
  410. ftpClient.setFileType(fileType);
  411. } catch (Exception e) {
  412. System.out.println("ftp设置传输文件的类型时失败!");
  413. }
  414. }
  415. /**
  416. * 关闭连接
  417. */
  418. public void closeConnect() {
  419. try {
  420. if (ftpClient != null) {
  421. ftpClient.logout();
  422. ftpClient.disconnect();
  423. }
  424. } catch (Exception e) {
  425. System.out.println("ftp连接关闭失败!");
  426. }
  427. }
  428. /**
  429. * 创建文件夹
  430. */
  431. public boolean createDirectory(String directory) {
  432. try {
  433. ftpClient.changeWorkingDirectory("/");
  434. String[] dirs = directory.split("/");
  435. String tempPath = "";
  436. for (String dir : dirs) {
  437. if (null == dir || "".equals(dir)) {
  438. continue;
  439. }
  440. tempPath += "/" + dir;
  441. if (!ftpClient.makeDirectory(tempPath)) {
  442. if (!ftpClient.changeWorkingDirectory(tempPath)) {
  443. return false;
  444. }
  445. } else {
  446. ftpClient.changeWorkingDirectory(tempPath);
  447. }
  448. }
  449. } catch (Exception e) {
  450. e.printStackTrace();
  451. }
  452. return true;
  453. }
  454. }