pom文件  这里只写重点配置

<!-- FTP -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.50</version>
        </dependency>
        <dependency>
            <groupId>hyxt.apollo</groupId>
            <artifactId>apollo-config-client</artifactId>
            <version>${apollo.config.client.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-codec</groupId>
                    <artifactId>commons-codec</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
<!-- easypoi  核心依赖包 -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

application.properties文件,只写重点代码

ftp.url=${apollo.ftp.url}
ftp.port=${apollo.ftp.port}
ftp.username=${apollo.ftp.username}
ftp.password=${apollo.ftp.password}
ftp.key=${apollo.ftp.key}
ftp.hrase=${apollo.ftp.hrase}

工具类

package com.hyxt.activity.cutprice.util;

import com.hyxt.emall.common.utils.CommonUtil;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

/**
 * 文件操作工具
 * @author PanJianPing
 */
public class FileUtil {
	/** 
	 * 上传、下载等全路径
	 * 调用这个方法的是上传操作,要获得的是上传文件在服务器本地的保存路径,这个地方我使用了File.separator,目前运行正常,不确定移植到Linux下是否正常.
	 * 估计这里要将path中的斜杠替换成 File.separator
	 */
	public static String getFilePath(HttpServletRequest request, String path, String shopid, Object filename) {
		String filePath = request.getSession().getServletContext().getRealPath(path);
		if (CommonUtil.isNotNull(shopid)) {
			filePath += File.separator + shopid;
		}

		if (CommonUtil.isNotNull(filename)) {
			filePath += File.separator + filename;
		}

		return filePath;
	}

	/**
	 * 保存相对路径
	 * 本来这个地方用的是File.separator,比如在window平台得到的是\,但用到这个函数的地方都是得到一个相对路径保存到表里用的,
	 * 比如生成页面后得到页面的路径:/cardpage\1\28.html
	 * 在list.jsp中预览链接写的是:${root}${item.pageurl}
	 * 在IE中,会自动将\转换为/,然后浏览器中新打开页面中显示正常,但在FF中显示的却是:http://localhost:8888/ecard/cardpage\1\28.html,导致404
	 */
	public static String getRelativeFilePath(String path, String shopid, Object filename) {
		String filePath = path;
		if (CommonUtil.isNotNull(shopid)) {
			filePath += "/" + shopid;
		}
		if (CommonUtil.isNotNull(filename)) {
			filePath += "/" + filename;
		}
		return filePath;
	}

	public static Long getMaxsize(String tagsize) {
		int length = Integer.parseInt(tagsize.substring(0, tagsize.length() - 1));
		String unit = tagsize.substring(tagsize.length() - 1).toLowerCase();

		Long max = null;
		if (unit.equalsIgnoreCase("k")) {
			max = new Long(length * 1024);
		} else if (unit.equalsIgnoreCase("m")) {
			max = new Long(length * 1024 * 1024);
		}
		return max;
	}


	/**
	 * 复制文件
	 * @param inputStream 	源文件输入流
	 * @param target 		目标文件
	 * @throws IOException
	 */
	public static void doCopyFromInputStream(InputStream inputStream, File target) throws IOException {
		target.getParentFile().mkdirs();

		BufferedInputStream in = new BufferedInputStream(inputStream);
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target));
		byte[] data = new byte[1024];
		while (in.read(data) != -1) {
			out.write(data);
		}
		out.flush();
		out.close();
		in.close();
	}

	/**
	 * 复制文件
	 * @param inputStream 源文件输入流
	 * @param targetPath  目标文件路径
	 */
	public static void copy(InputStream inputStream, String targetPath) throws IOException {
		File target = new File(targetPath);
		doCopyFromInputStream(inputStream,target);
	}

	/**
	 *
	 * @param inputStream	源文件输入流
	 * @param target		目标文件
	 * @throws IOException
	 */
	public static void copy(InputStream inputStream, File target) throws IOException {
		doCopyFromInputStream(inputStream,target);
	}

	/**
	 * 复制文件
	 *
	 * @param source 源文件
	 * @param target 目标文件
	 */
	public static void doCopyFromFile(File source, File target) throws IOException {
		target.getParentFile().mkdirs();// 保证文件所在目录一定存在
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target));
		byte[] data = new byte[1024];
		while (in.read(data) != -1) {
			out.write(data);
		}
		out.flush();
		out.close();
		in.close();
	}

	/**
	 * 复制文件
	 *
	 * @param source 	 源文件
	 * @param targetPath 目标文件路径
	 */
	public static void copy(File source, String targetPath) throws IOException {
		File target = new File(targetPath);
		doCopyFromFile(source, target);
	}

	/**
	 * 复制文件
	 *
	 * @param sourcePath 源文件路径
	 * @param targetPath 目标文件路径
	 */
	public static void copy(String sourcePath, String targetPath) throws IOException {
		File source = new File(sourcePath);
		File target = new File(targetPath);
		doCopyFromFile(source, target);
	}

	/**
	 * 允许上传的文件类型
	 *
	 * @param allowFileTypes
	 * @return
	 */
	public static boolean isAllowFileType(String[] allowFileTypes, String filename) {
		// 对文件类型的判断
		String filetype = getLowerCaseFileType(filename);
		if (CommonUtil.isNotNull(allowFileTypes)) {
			for (String type : allowFileTypes) {
				if (filetype.equalsIgnoreCase(type.toLowerCase())) {
					return true;
				}
			}
			return false;
		} else {
			// 默认所有都可以上传
			return true;
		}
	}

	/**
	 * 上传文件(Spring上传)
	 * @param request
	 * @param uploadFileFormName 文件域名
	 * @param allowFileTypes 所允许上传的文件类型(null时为全部)
	 * @throws Exception
	 */
	public static String uploadFile(DefaultMultipartHttpServletRequest request, String targetPath, String uploadFileFormName, String[] allowFileTypes) throws Exception{
		DefaultMultipartHttpServletRequest mRequest = request; //new DefaultMultipartHttpServletRequest(request);
		MultipartFile uFile = mRequest.getFile(uploadFileFormName);
		//判断上传的文件是否有内容
		if (uFile == null || uFile.isEmpty()) {
			return null;
		}

		//原文件名
		String filename = uFile.getOriginalFilename();
		//是否允许上传
		boolean allowable  = isAllowFileType(allowFileTypes, filename);

		if (allowable) {
			targetPath += filename.substring(filename.lastIndexOf("."));
			//开始上传
			InputStream inputStream = uFile.getInputStream();
			copy(inputStream, targetPath);
			return filename;
		}else{
			throw new Exception("上传文件类型错误");
		}
	}

	/** 得到小写的文件类型,不带.号 */
	public static String getLowerCaseFileType(String filename) {
		if (CommonUtil.isNotNull(filename)) {
			int position = filename.lastIndexOf(".");
			if (position <= 0) {
				return null;
			} else {
				return filename.substring(position + 1).toLowerCase();
			}
		} else {
			return null;
		}
	}

	/** 得到文件名后缀,即带.号的文件类型 */
	public static String getLowerCaseSuffix(String filename){
		if (CommonUtil.isNotNull(filename)) {
			int position = filename.lastIndexOf(".");
			if (position <= 0) {
				return null;
			} else {
				return filename.substring(position).toLowerCase();
			}
		}else{
			return null;
		}
	}



    /**
     *  根据路径删除指定的目录或文件,无论存在与否
     *@param sPath  要删除的目录或文件
     *@return 删除成功返回 true,否则返回 false。
     */
    public static boolean deleteFolder(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists()) {  // 不存在返回 false
            return flag;
        } else {
            // 判断是否为文件
            if (file.isFile()) {  // 为文件时调用删除文件方法
                flag = deleteFile(sPath);
                return deleteFile(sPath);
            } else {  // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

    /**
     * 删除单个文件
     * @param   sPath    被删除文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录(文件夹)以及目录下的文件
     * @param   sPath 被删除目录的文件路径
     * @return  目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在,或者不是一个目录,则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) break;
            } //删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

}
package com.hyxt.activity.cutprice.util;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by test on 2015/9/1.
 */
public class SFtpUtil {

    /**
     * 建立连接
     *
     * @param ip
     * @param user
     * @param psw
     * @param port
     * @param privateKey
     * @param passphrase
     * @return
     * @throws Exception
     */
    private static Session connect(String ip, int port, String user, String psw, String privateKey, String passphrase) throws Exception {
        Session session = null;
        JSch jsch = new JSch();
        //设置密钥和密码
        if (privateKey != null && !privateKey.isEmpty()) {
            if (passphrase != null && !passphrase.isEmpty()) {
                //设置带口令的密钥
                jsch.addIdentity(privateKey, passphrase);
            } else {
                //设置不带口令的密钥
                jsch.addIdentity(privateKey);
            }
        }
        if (port <= 0) {
            //连接服务器,采用默认端口
            session = jsch.getSession(user, ip);
        } else {
            //采用指定的端口连接服务器
            session = jsch.getSession(user, ip, port);
        }

        //如果服务器连接不上,则抛出异常
        if (session == null) {
            throw new Exception("session is null");
        }

        //设置登陆主机的密码
        session.setPassword(psw);//设置密码
        //设置第一次登陆的时候提示,可选值:(ask | yes | no)
        session.setConfig("StrictHostKeyChecking", "no");
        //设置登陆超时时间
        session.connect(30000);
        return session;
    }

    /**
     * 利用JSch包实现SFTP上传文件
     *
     * @param ip         主机IP
     * @param user       主机登陆用户名
     * @param psw        主机登陆密码
     * @param port       主机ssh2登陆端口,如果取默认值(默认值22),传-1
     * @param privateKey 密钥文件路径
     * @param passphrase 密钥的密码
     */
    public static void upload(String ip, int port, String user, String psw, String privateKey, String passphrase, String remoteDirPath, String remoteFileName, InputStream inputStream) {
        Session session = null;
        Channel channel = null;
        OutputStream outstream = null;
        try {
            session = connect(ip, port, user, psw, privateKey, passphrase);
            //创建sftp通信通道
            channel = (Channel) session.openChannel("sftp");
            channel.connect(1000);
            ChannelSftp sftp = (ChannelSftp) channel;

            //进入服务器指定的文件夹
            String[] dirs = remoteDirPath.split("/");
            for (String dir : dirs) {
                if (dir != null && !dir.isEmpty()) {
                    try {
                        sftp.mkdir(dir);
                    } catch (Exception e) {
                    }
                    sftp.cd(dir);
                }
            }

            outstream = sftp.put(remoteFileName);
            byte b[] = new byte[1024];
            int n;
            while ((n = inputStream.read(b)) != -1) {
                outstream.write(b, 0, n);
            }
            outstream.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {

                }
            }
            if (outstream != null) {
                try {
                    outstream.close();
                } catch (Exception e) {

                }
            }
            if (session != null) {
                session.disconnect();
            }
            if (channel != null) {
                channel.disconnect();
            }
        }
    }

    /**
     * 利用JSch包实现SFTP下载文件
     *
     * @param ip         主机IP
     * @param user       主机登陆用户名
     * @param psw        主机登陆密码
     * @param port       主机ssh2登陆端口,如果取默认值(默认值22),传-1
     * @param privateKey 密钥文件路径
     * @param passphrase 密钥的密码
     */
    public static void download(String ip, int port, String user, String psw, String privateKey, String passphrase, String remoteDirPath, String remoteFileName, String localDirPath, String localFileName) {
        Session session = null;
        Channel channel = null;
        FileOutputStream outStream = null;
        InputStream inStream = null;
        try {
            session = connect(ip, port, user, psw, privateKey, passphrase);

            //创建sftp通信通道
            channel = (Channel) session.openChannel("sftp");
            channel.connect(1000);
            ChannelSftp sftp = (ChannelSftp) channel;

            //进入服务器指定的文件夹
            String[] dirs = remoteDirPath.split("/");
            for (String dir : dirs) {
                if (dir != null && !dir.isEmpty()) {
                    try {
                        sftp.mkdir(dir);
                    } catch (Exception e) {
                    }
                    sftp.cd(dir);
                }
            }
            createDir(localDirPath);
            File file = new File(localDirPath + File.separator + localFileName);
            outStream = new FileOutputStream(file);
            inStream = sftp.get(remoteFileName);
            byte b[] = new byte[1024];
            int n;
            while ((n = inStream.read(b)) != -1) {
                outStream.write(b, 0, n);
            }
            outStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (outStream != null) {
                    outStream.close();
                }
                if (inStream != null) {
                    inStream.close();
                }
            } catch (Exception e) {
                // ignore close exception
            }
            if (session != null) {
                session.disconnect();
            }
            if (channel != null) {
                channel.disconnect();
            }
        }
    }

    /**
     * 创建目录
     *
     * @param path 文件夹路径
     */
    public static void createDir(String path) {
        try {

            File file = new File(path);
            //判断文件夹是否存在,如果不存在则创建文件夹
            if (!file.exists()) {
                file.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
@Controller
@RequestMapping("/web")
public class CutpriceController extends AbstractBaseController{

@Value("${ftp.url}")
	private String ftp_url;
	@Value("${ftp.port}")
	private Integer ftp_port;
	@Value("${ftp.username}")
	private String ftp_username;
	@Value("${ftp.password}")
	private String ftp_password;
	@Value("${ftp.key}")
	private String ftp_key;
	@Value("${ftp.hrase}")
	private String ftp_hrase;
	private String ftpDir = "/dbdata/nds/cutprice/";



@RequestMapping("/dowunloadExport/{sha1Hex}")
	public String dowunloadExport(@PathVariable String sha1Hex, Model model){
		model.addAttribute("sha1Hex",sha1Hex);
		return "/web/cutprice/downloadExport";
	}

	/**
	 * js定时查询
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getExportExcel")
	@ResponseBody
	public Map<String, String> getExportExcel(HttpServletRequest request) {

		Map<String, String> map = new HashMap<String, String>(2);

		String sha1Hex = request.getParameter("sha1Hex");
		//查询缓存里是否存在
		String fileKey = "nds:cutprice:excelFile:" + sha1Hex;
		String stateKey = "nds:cutprice:excelState:" + sha1Hex;
		if (stringRedisTemplate.hasKey(fileKey)) {
			map.put("ordersExcelFile", stringRedisTemplate.opsForValue().get(fileKey));
			return map;
		}
		if (stringRedisTemplate.hasKey(stateKey)) {
			map.put("state", "0");
		}
		return map;
	}

	/**
	 * 导出的活动信息列表下载
	 *
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/exportDownloadCutpriceExcel/{sha1Hex}")
	public void exportDownloadCutpriceExcel(HttpServletResponse response,@PathVariable String sha1Hex) {
		String shopId =getShopId();
		OutputStream outputStream = null;
		FileInputStream inputStream = null;
		File file = null;
		String fileName = "砍价活动信息";
		try {
//			String sha1Hex = request.getParameter("sha1Hex");
			String value = stringRedisTemplate.opsForValue().get("nds:cutprice:excelFile:"+sha1Hex);
			String catalog = ftpDir + shopId; // ftp目录
			String realPath =  getRealPath(request);
			String outputFilePath = realPath + ("template" + File.separator + "cutprice" );
			File directory = new File(outputFilePath);
			if (! directory.exists()){
				directory.mkdir();
			}
			SFtpUtil.download(ftp_url, ftp_port, ftp_username, ftp_password, ftp_key, ftp_hrase, catalog, value, outputFilePath, value);
			String localFile = outputFilePath + File.separator +value;
			file = new File(localFile);
			logger.info("导出砍价活动信息时,从ftp:{}/{}, 下载到本地:{} 完成", catalog ,value ,localFile);
			if (file != null) {
				inputStream = new FileInputStream(file);
				String name ;
				if (file.getName().endsWith(".zip")) {
					response.setContentType("application/x-zip-compressed");
					name = new String( (fileName + ".zip").getBytes("GBK"), "ISO8859-1");
				} else {
					response.setContentType("application/vnd.ms-excel");
					name = new String((fileName + ".xls").getBytes("GBK"), "ISO8859-1");
				}
				response.addHeader("Content-Disposition", "attachment;  filename=" + name);
				outputStream = response.getOutputStream();
				int temp = 0;
				while ((temp = inputStream.read()) != -1) {
					outputStream.write(temp);
				}
			}
		} catch (Exception e) {
			logger.error("砍价活动信息:{},批量导出:{},从ftp下载异常",shopId,fileName,e);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
				}
			}
			try {
				if (outputStream != null) {
					outputStream.flush();
					outputStream.close();
				}
			} catch (IOException e) {
				//
			}
			if (file != null) {
				file.delete(); // 删除本地文件
			}
		}
	}

	/**
	  * @description:导出砍价活动情况的数据
	  * @param []
	  * @return
	  * @throws
	  * @author Gavin.luo
	  * @date 2022/3/18 15:58
	  */
	@RequestMapping("/exportCutpriceQkInfoList/{activityId}")
	@ResponseBody
	public String exportCutpriceQkInfoList(HttpServletResponse response,@PathVariable String activityId){
		String realPath = request.getServletContext().getRealPath("/");
		String sessionId = request.getSession().getId();
		String sha1Hex = DigestUtils.sha1Hex(sessionId);
		Integer total=0;
		String storeId;
		if(getTopStoreId().equals(getUserSelectStoreId())){
			total = cutpriceService.queryActivityCutpriceCount(getShopId(), null,activityId);
			storeId=null;
		}else{
			//分店
			total = cutpriceService.queryActivityCutpriceCount(getShopId(),getUserSelectStoreId(),activityId);
			storeId = getUserSelectStoreId();
		}
		logger.info("total------------->"+total+"------storeId---------------->"+storeId);
		exportCutprice(total, getShopId(),storeId, sessionId, activityId, realPath,sha1Hex);
		return sha1Hex;
	}

	private void exportCutprice(Integer totalRecord,String shopId,String storeId,String sessionId, String activityId,String realPath,String sha1Hex){
		ExecutorService threadPool = null;

		try {
			threadPool = Executors.newCachedThreadPool();
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					try {
						stringRedisTemplate.delete("nds:cutprice:excelFile:" + sha1Hex);
						String ordersExcelFile = exportZipExcel(totalRecord,shopId,storeId,activityId,realPath);
						stringRedisTemplate.opsForValue().set("nds:cutprice:excelFile:" + sha1Hex, ordersExcelFile, 20, TimeUnit.MINUTES);
					} catch (Exception e) {
						stringRedisTemplate.opsForValue().set("nds:cutprice:excelState:" + sha1Hex, "0", 5, TimeUnit.MINUTES);
						logger.error("导出砍价活动信息失败:", e);
					}
				}
			};
			threadPool.execute(runnable);
		} catch (Exception e) {
			stringRedisTemplate.opsForValue().set("nds:cutorice:excelState" + sha1Hex, "0", 5, TimeUnit.MINUTES);
			logger.error("导出砍价活动信息失败:", e);
		} finally {
			if (threadPool != null) {
				threadPool.shutdown();
			}
		}
	}

	@Transactional(readOnly = true)
	public String exportZipExcel(Integer totalRecord,String shopId,String storeId,String activityId,String realPath) throws Exception{

		int totalPage = totalRecord % EXPORT_SIZE == 0 ? totalRecord / EXPORT_SIZE : totalRecord / EXPORT_SIZE + 1;
		List<String> pathList = new ArrayList<String>();
		for (int i = 0; i < totalPage; i++) {
			String outputFilePath = realPath + ("tpl" + File.separator + UUID.randomUUID() + ".xlsx");
			File directory = new File(realPath+"tpl");
			if (! directory.exists()){
				directory.mkdir();
			}
			String path = exportFileExcel(shopId,storeId,activityId, outputFilePath, i, EXPORT_SIZE);
			pathList.add(path);
		}
		logger.info("pathList---------------->"+ JSON.toJSONString(pathList));
		// 压缩文件
		String outputFilePath = realPath + ("tpl" + File.separator + UUID.randomUUID() + ".zip");
		File zipFile = new File(outputFilePath);
		InputStream input = null;
		ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
		zipOut.setEncoding("GB2312");
		for (int i = 0; i < pathList.size(); i++) {
			File f = new File(pathList.get(i));
			input = new FileInputStream(f);
			zipOut.putNextEntry(new ZipEntry("砍价活动信息" + (i + 1) + ".xlsx"));
			int temp = 0;
			while ((temp = input.read()) != -1) {
				zipOut.write(temp);
			}
			input.close();
		}
		zipOut.close();

		//文件上传FTP
		FileInputStream fileInputStream = null;
		String fileName = null;
		try {
			String catalog = ftpDir + getShopId(); // ftp目录
			fileName = zipFile.getName(); // 文件名称
			fileInputStream = new FileInputStream(zipFile);
			SFtpUtil.upload(ftp_url, ftp_port, ftp_username, ftp_password, ftp_key, ftp_hrase, catalog, fileName, fileInputStream);
//			filePath = fileName; //完整的ftp 文件路径
			logger.info("导出砍价活动信息列表,生成文件:{}, ftp:{} 完成", zipFile.getPath(), fileName);
		} catch (Exception e) {
			logger.info("导出砍价活动信息列表,异常", e);
		} finally {
			try {
				if (zipFile != null && zipFile.exists()) {
					zipFile.delete();
				}
			} catch (Exception e) {
			}// 删除本地文件
			try {
				if (fileInputStream != null) {
					fileInputStream.close();
				}
			} catch (Exception e) {
			}
		}

		for (String s : pathList) {
			FileUtil.deleteFile(s);
		}
		FileUtil.deleteFile(outputFilePath);
		return fileName;

	}

	@Transactional(readOnly = true)
	public String exportFileExcel(String shopId,String storeId,String activityId,String outputFilePath,Integer page,Integer pageSize){
		FileOutputStream outStream = null;
		List<ActivityCutpriceQkVo> result = cutpriceService.queryActivityCutpriceQkList(shopId,storeId,activityId,page,pageSize);
		logger.info("size===>"+result.size());

		List<ActivityCutpriceQkExportVo> exportVos = new ArrayList<>();
		result.stream().forEach(o->{
			ActivityCutpriceQkExportVo vo = new ActivityCutpriceQkExportVo();
			BeanUtils.copyProperties(o,vo);
			ElActivityVo activity = null;
			try {
				activity = elActivityService.findActivityById(activityId, getShopId());
			} catch (ElActivityException e) {
				e.printStackTrace();
			}
			if(CommonUtil.isNotNull(activity)) {
				vo.setActivityName(activity.getTitle());
			}
			exportVos.add(vo);
		});
		try {
			Workbook workbook = (new ExcelUtil<ActivityCutpriceQkExportVo>() {
			}).getWork(exportVos);
			File outputFile = new File(outputFilePath);
			outStream = new FileOutputStream(outputFile);
			workbook.write(outStream);
//			OutputStream output = response.getOutputStream();
//			response.reset();
//			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmm");
//			String filename = "导出列表".concat(sdf.format(new Date(System.currentTimeMillis())));
//			response.setHeader("Content-disposition", "attachment; filename=" + filename + ".xlsx");
//			// 跨域
//			response.setHeader("Access-Control-Allow-Origin", "*");
//			response.setContentType("application/msexcel");
//			workbook.write(output);
//			output.close();
		}catch (Exception e){
			logger.info(e.getMessage());
		}finally {
			if (outStream != null) {
				try {
					outStream.close();
				} catch (IOException e) {
					logger.error("关闭文件输入流异常" + e.getMessage());
				}
			}
		}
		return outputFilePath;
	}


}

jsp代码

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/commons/taglibs.jsp" %>
<!DOCTYPE html>
<html>
<%@include file="/commons/headTag.jsp" %>
<%@include file="/commons/javascript.jsp" %>
<script type="text/javascript" src="${root}/resources/js/jquery.form.js"></script>
<script type="text/javascript" src="${root}/resources/js/page.js"></script>
<script src="${root}/resources/js/jquery.json-2.3.min.js"></script>

<body>
<form id="queryGoodsForm1" method="post" action="${root}/web/downloadExportExcel">
    <input type="hidden" id="sha1Hex" value="${sha1Hex}">
    <input type="hidden" id="ftpFileName">
    <body style="align-items: center">
    <div id="showMessage"  class="span">正在下载...请勿关闭</div>
    <div id="downLoadMessage" style="display: none" class="span">导出成功...<a class="c-3277de" id="dld">下载</a></div>
    <div id="downloadFaild" style="display: none" class="span">生成导出文件失败,请稍后再试!</div>
    </body>
</form>
<script>
    setInterval(getOrdersExcel, 3000);

    function getOrdersExcel() {
        var sha1Hex = $('#sha1Hex').val();
        if (!sha1Hex) {
            return;
        }
        $.post("${root}/web/getExportExcel", {sha1Hex: sha1Hex}, function (data) {
            if (data) {
                if (data.ordersExcelFile) {
                    $("#showMessage").attr("style", "display: none");
                    $("#downLoadMessage").attr("style", "display: block");
                    $("#ftpFileName").val(data.ordersExcelFile)
                    $("#dld").attr("href","${root}/web/exportDownloadCutpriceExcel/"+sha1Hex);
                } else if (data.state == 0) {
                    $("#showMessage").attr("style", "display: none");
                    $("#downloadFaild").attr("style", "display: block");
                }
            }
        });
    }
    function exportDownloadExcel(){
        $("#queryGoodsForm1").submit();
    }
</script>
</html>