最近项目中做了一个需求,就是将多个excel打包并且压缩到ZIP中,并且通过浏览器下载到本地,觉得这是个值得积累的例子,所以就整理下来了,希望对需要的同学有用。
本需求设计思路分为几步:1.需要再硬盘上保存一个用于读取的excel模板,目录可以自己设置,可以用于直接下载文件,也可以用于向文件中写入内容然后再下载,关于excel读写内容的具体详情,以后会在其他博客中详细描述,这里不多解释。
2.通过IO流读取excel模板文件
代码如下:
public void export(IActionContext context) throws ParsePropertyException,
InvalidFormatException, IOException, ParseException, IllegalAccessException,
InvocationTargetException{
//保存文件名
List<String[]> filesList = new ArrayList<>();
//具体向集合中加文件名
String[] fileNameGore = exportFilesToExcel(map, filesList);
// 打开IO流
String outputFileName = VoaDinfUtil.getBbsUploadRealPath() + File.separator
+ VoaDinfUtil.getUploadFilename("压缩包名称.zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFileName));
// 注意此处编码设置 支持中文
out.setEncoding("GBK");
for (String[] fileNames : filesList) {
File file = new File(fileNames[0]);
if (file != null && file.exists()) {
// 尝试用NIO方式
FileInputStream input = new FileInputStream(file);
// FileChannel channel=new FileInputStream(file).getChannel();
out.putNextEntry(new ZipEntry(fileNames[1]));
int temp = 0;
byte[] b = new byte[1024];
// ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while ((temp = input.read(b)) != -1) {
// while ((temp = channel.read(byteBuffer)) != -1) {
out.write(b, 0, temp);
// out.write(byteBuffer.array());
}
input.close();
// channel.close();
}
}
// 关闭IO
out.close();
// 重定向到文件下载Servlet
String exportUrl = "/servlet/fileUploadNewServlet?action=export&filePathName=" +
Code.encode(outputFileName)
+ "&fileName=" + Code.encode("压缩包.zip");
}
//查询数据并且将excel保存到本地路径
private String[] exportGoreToExcel(Map<String, String> map, List<String[]> filesList) {
Map<String, String> paramMap = new HashMap<>();
paramMap.putAll(map);
List<VoaGoreIssueMissVO> dataList = queryGoreMissClearList(paramMap);
if (null == dataList || dataList.size() == 0) {
return null;
}
Map<String, List> xlsMap = new HashMap<>();
List<String> closeDatelist = new ArrayList<>();
try {
closeDatelist.add(UtilDatetime.FormatDate(UtilDatetime.getLastMonthLastDay(), "yyyy年MM月dd日"));
} catch (ParseException e1) {
log.error("查询日期格式转化异常:" + e1.getMessage());
}
xlsMap.put("closeDate", closeDatelist);
try {
String fileName[] = new VoaExcelUtil().exportToExcelOrZip(dataList, "excel文件名", "frecNotPairDetail",
"frecNotPairDetail.xlsx", xlsMap);
return fileName;
} catch (IllegalAccessException | InvocationTargetException | IOException | ParseException e) {
log.error("导出失败:" + e.getMessage());
}
return null;
}
public class FileUploadNewServlet extends HttpServlet {
public FileUploadNewServlet() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
IOException, ServletException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws
IOException, ServletException {
handleExport(request, response);
}
private void handleExport(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String filePathName = Code.decode(request.getParameter("filePathName"));
String fileName = Code.decode(request.getParameter("fileName"));
String notDeleteFile = request.getParameter("notDeleteFile");
Assert.notNull(filePathName);
File dlFile = new File(filePathName);
if (!dlFile.exists())
return;
response.reset();
response.addHeader("Content-Disposition",
"attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1"));
response.addHeader("Content-Length", dlFile.length() + "");
response.setContentType("application/octet-stream;;charset=ISO8859-1");
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
// outputStream.write(UtilFile.read(filePathName));//解决文件过大内存溢出
InputStream fis = new BufferedInputStream(new FileInputStream(dlFile));
byte[] buffer = new byte[1024 * 1024 * 4];
int i = -1;
while ((i = fis.read(buffer)) != -1) {
outputStream.write(buffer, 0, i);
response.flushBuffer();
}
outputStream.close();
outputStream = null;
response.flushBuffer();
fis.close();
if ((notDeleteFile == null || notDeleteFile.equals("0")) && dlFile.exists() && dlFile.isFile())
dlFile.delete();
}
}