POI导出时写一份到ftp服务器,一份下载给客户端
导语:
昨天接到项目经理这么一个需求,让我在POI导出Excel的时候写一份到我之前搭建的ftp服务器上。所以就有了这篇博客首先我们来分析下之前的业务逻辑:我们创建并构造了一个workbook,然后构建了一个OutputStream输出流,然后我们把数据写入输出流中就可以被客户端下载。
现在我们要在此基础上写一份到ftp服务器
那么我们就需要两个流,首先一个输入流把文件写到ftp服务器,然后需要一个输出流把文件输出到客户端。千万不要用workbook.write(out)一份到客户端,然后又workbook.write(in)一份到ftp,会报错的。Stream is closed,(为啥报错,我也解释不清希望大神解惑一下)
正确思路应该是先写一份到ftp服务器,然后再读取这个文件,然后再把这个文件输出给客户端
参考:
来看代码吧:
1. 我们只需要对 oi实现百万级数据导出 中的 CommentController 稍作修改,然后配合一些工具类就可以实现
/**
* excel导出功能
* @param commentSearch
* @param response
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/exportCommentInfo")
@ResponseBody
@NoRepeatRequest
public BaseDTO exportCommentInfo(CommentSearch commentSearch, HttpServletResponse response, HttpServletRequest request) throws Exception{
LOGGER.info("CommentController.exportCommentInfo start");
long startTime = System.currentTimeMillis();
LOGGER.info("开始下载.........................................");
List<ErrorInfo> errors = null;
int result = ;
String fileName = FileNameUtils.getExportCommontExcelFileName();
OutputStream fileOut = null;
SXSSFWorkbook workbook = null;
try {
LOGGER.debug("classpath: " + fileName);
workbook = new SXSSFWorkbook();
commentService.exportCommentInfo(request,workbook, commentSearch);
// 定义excel文件名
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\""
+ URLEncoder.encode(fileName, "UTF-8") + "\"");
// 定义输出流
fileOut = response.getOutputStream();
// 调用导出方法
//workbook.write(fileOut);
//写一份到ftp服务器
ByteArrayOutputStream os = new ByteArrayOutputStream();
workbook.write(os);
byte[] b = os.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(b);
FtpUtil.uploadFileToFtp(fileName,in,fileOut);
workbook.dispose();
} catch (Exception e) {
LOGGER.error("InterfaceInfoController.exportInterfaceInfo Exception: ", e);
ErrorInfo errorInfo = new ErrorInfo("system.error", "系统异常!");
errors = Arrays.asList(errorInfo);
request.getSession().setAttribute("exportStatus","error");
}finally {
fileOut.close();
workbook.close();
}
LOGGER.info("下载完成....|||||.......用时:" + (System.currentTimeMillis() - startTime));
return tranferBaseDTO(errors, result);
}
1.首先把workbook写到 ByteArrayOutputStream 输出流中,然后转换成 字节数组 byte[] b 在转换成 ByteArrayInputStream 输入流用来写入ftp
ByteArrayOutputStream os = new ByteArrayOutputStream();
workbook.write(os);
byte[] b = os.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(b);
FtpUtil.uploadFileToFtp(fileName,in,fileOut);
2.然后转换成 字节数组 在转换成输入流用来写入ftp ,主要看这几个方法
/**
* 上传重载 二进制流
* @param filename
* @param input
* @return
*/
public static boolean uploadFileToFtp(String filename, ByteArrayInputStream input, OutputStream fileOut) {
getPropertity();
return uploadFileToFtp( host, port, username, password, basePath,
filePath, filename, input, fileOut);
} /**
* Description: 向FTP服务器上传文件 二进制流文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @return 成功返回true,否则返回false
*/
public static boolean uploadFileToFtp(String host, String port, String username, String password, String basePath,
String filePath, String filename, ByteArrayInputStream input, OutputStream fileOut) {
FTPClient ftp = new FTPClient();
try {
//开启ftp连接
boolean result = connectFtp(ftp, host, port, username, password, basePath, filePath);
if(!result){
return result;
}
if (FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
if (FTPReply.isPositiveCompletion(ftp.sendCommand("OPTS UTF8", "ON"))) {
LOCAL_CHARSET = "UTF-8";
}
}
//防止中文乱码
filename = new String(filename.getBytes(LOCAL_CHARSET),SERVER_CHARSET );
//为了加大上传文件速度,将InputStream转成BufferInputStream , InputStream input
BufferedInputStream in = new BufferedInputStream(input);
//加大缓存区
ftp.setBufferSize(1024*1024);
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if (!ftp.storeFile(filename, in)) {
return false;
}
//写一份给客户端
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(filename)) {
ftp.retrieveFile(ff.getName(), fileOut);
fileOut.close();
}
}
in.close();
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return true;
} /**
* 连接ftp服务器并切换到目的目录
* 调用此方法需手动关闭ftp连接
* @param ftp
* @param host
* @param port
* @param username
* @param password
* @param basePath
* @param filePath
* @return
*/
private static boolean connectFtp( FTPClient ftp,String host, String port, String username, String password, String basePath, String filePath){
boolean result = false;
try {
int portNum = Integer.parseInt(port);
int reply;
// 连接FTP服务器
ftp.connect(host, portNum);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if (!ftp.changeWorkingDirectory(basePath+filePath)) {
//如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir)) {
continue;
}
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
result = true;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
主要是 我们为了加快文件上传速度把刚才传入的 ByteArrayInputStream 转换成了 BufferedInputStream
BufferedInputStream in = new BufferedInputStream(input);
然后我们把 BufferedInputStream 写入到ftp服务器
ftp.storeFile(filename, in)
到这里第一步就完成了,接下来是从服务器下载我们刚才上传 文件,然后通过刚才传入的 输出流 fileOut 输出到客户端
//写一份给客户端
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(filename)) {
ftp.retrieveFile(ff.getName(), fileOut);
fileOut.close();
}
}
POI导出时写一份到ftp服务器,一份下载给客户端的更多相关文章
- 使用批处理文件在FTP服务器 上传下载文件
1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt 192.168.1.1 建立一个 ...
- Spring学习---Spring中利用组件实现从FTP服务器上传/下载文件
FtpUtil.java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcepti ...
- ftp服务器上传下载共享文件
1 windows下搭建ftp服务器 https://blog.csdn.net/qq_34610293/article/details/79210539 搭建好之后浏览器输入 ftp://ip就可以 ...
- POI导出时,将指定的列设置为下拉列表
本示例设置第2列为下拉框(下拉框内容为:是/否),从第5行开始到5657行结束. 关键代码示例: ComboxList = new String[]{"是","否&quo ...
- WordPress更新时提示无法连接到FTP服务器的解决方案
这几天在搭建主站的时候,更新wordpress时无法连接到FTP原因服务器 解决方法如下: 在WordPress目录下找到wp-config.php文件并编辑,在最后一行加上: define('FS_ ...
- 从ftp服务器进行批量下载,处理文件名保存时重名的问题,更改重名文件名方式为给后面加1、2、3等数字,保持后缀不变
公司最近有一个从ftp批量下载文件的需求,但是文件名重复总会报错 没办法,自己下班后写了一个小算法 仿照桶排序的原理,实现了这个小功能,直接上代码: String[] test = {"ha ...
- Node.js使用ftp连接远程ftp服务器枚举和下载文件示例
示例代码: var Ftp = require('ftp'); var fs = require('fs'); var path = require('path'); // 首先判断参数中是否包含{d ...
- FTP服务器的搭建与配置
主要来源:http://www.cnblogs.com/helonghl/articles/5533857.html 1.安装FTP服务器: yum install vsftpd -y 2.启动FTP ...
- Ubantu下FTP服务器资源进行控制
在FTP服务器的管理中无论对本地用户还是匿名用户,对于FTP服务器资源的使用都需要进行控控制, 避免由于负担过大造成FTP服务器运行异常, 可以添加以下配置项对FTP客户机使用FTP服务器资源进行控制 ...
随机推荐
- c++实现“扫描检测硬件改动”
这里需要用到cfgmgr32.h,参考了网上好几篇博文. #include <windows.h> #include <stdio.h> #include <cfgmgr ...
- 抓取awr、语句级awr、ashrpt
exec dbms_workload_repository.create_snapshot();--调用MMON进程立即收集快照 生成AWR报告@?/rdbms/admin/awrrpt.sql; 9 ...
- mint-ui之Loadmore使用
<template> <div class="page-loadmore"> <div class="page-loadmore-wrapp ...
- java后端学习路线
java基础-->java设计模式-->java数据结构与算法
- 从Hello World说起(Dart)到“几乎所有东西都是Widget”小部件。
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends S ...
- 再谈 linux 的sed用法
很多东西, 如果太复杂, 太庞杂, 一开始, 可以只掌握最简单的. 如果连最简单的都不能掌握, 那看那么多有什么用? 关于cut, sed的 处理过程和思想? vm: virtual machine, ...
- 4514: [Sdoi2016]数字配对 费用流
链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4514 思路 EK直接贪心做 <0的时候加上剩余返回 二分图a->b的时候 把b- ...
- 【server.properties】kafka服务设置
每个kafka broker中配置文件server.properties默认必须配置的属性如下: broker.id=0 num.network.threads=2 num.io.threads=8 ...
- Latex: 添加IEEE论文keywords
参考: How to use \IEEEkeywords Latex: 添加IEEE论文keywords 方法: \begin{IEEEkeywords} keyword1, keyword2. \e ...
- HDU 2426 Interesting Housing Problem(二分图最佳匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2426 题意:每n个学生和m个房间,现在要为每个学生安排一个房间居住,每个学生对于一些房间有一些满意度,如果满意度 ...