在最近的业务工作中遇到了这样的一个需求,将数据库的数据筛选拿去出来,做成excel和word文件,并将这些进行汇总,返回一个压缩包(zip)文件。
但是好像网上很多的代码都是一样的,有一些甚至都不能跑起来!所以我将自己所理解的业务逻辑进行梳理和功能代码进行展示
service层的实现
public void exportPolicy(HttpServletResponse response, List<Long> idList) throws IOException{
/*1、向数据库中查询相关数据*/
//业务筛选逻辑,这里all列表表示结果
File file1 = null;
ServletOutputStream out = response.getOutputStream();
try {
/*2、创建临时文件夹*/
//获取main目录(工程)
String path = FileExportUtils.getHomePath();
//创建临时文件夹用于存放文件
File tempFile = new File(path+"/tempFile");
if (!tempFile.exists()){
tempFile.mkdirs();
}
//创建文件夹
file1 = new File(tempFile.getPath()+"/"+System.currentTimeMillis());
file1.mkdirs();
//创建用于盛放政策word的文件夹
File policyDir = new File(file1.getPath()+"/"+"policy");
policyDir.mkdirs();
/*3、将查询到的数据做成excel和word文件*/
//拿取到excel对象
HSSFWorkbook excel = FileExportUtils.getExcel(all);
//将excel写入file1中
if (null != excel){
File excelFile = new File(file1.getPath()+"/details.xls");
FileExportUtils.writeExcel(excelFile.getPath(),excel);
}
//将word写入policyDir中(这里对象不用管!!)
for (NewPolicy policy : all) {
POIFSFileSystem word = FileExportUtils.getWord(policy);
if (word == null) continue;
File file = new File(policyDir.getPath()+"/"+policy.getTitle()+".doc");
FileExportUtils.writeWord(file.getPath(),word);
}
/*4、对file1目录进行压缩打包并且返回*/
byte[] data = FileExportUtils.getZip(file1.getPath());
//创建压缩包
String zipName = file1.getName()+".zip";
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(zipName, "utf-8"));
response.addHeader("Content-Length",""+data.length);
response.setContentType("application/octet-stream;charset=UTF-8");
IOUtils.write(data,out);
}catch (Exception e){
log.info("压缩文件出错");
}finally {
try {
//删除file1
if (file1.exists()){
FileExportUtils.deleteDir(file1);
}
//关闭相应流
if (null != out){
out.flush();
out.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
以上有一些与本文无关的对象就不用理会!生成excel和word相关方法亦不必例会!
工具类FileExportUtils实现
获取运行时项目路径,这里我选的是main路径
APP_NAME就是你项目的名称
/**
*
* 功能描述: 获取运行时main目录,添加file目录作为压缩导出文件
*
*/
public static String getHomePath(){
String userDir = System.getenv(APP_NAME);
// System.out.println(userDir);
if (userDir == null){
userDir = System.getProperty("user.dir");
}
if (userDir.endsWith("bin")){
userDir =userDir.substring(0,userDir.length()-4);
}else {
String separator = File.separator;
if (userDir.contains("testdemo")) {
userDir = userDir + separator + "src" + separator + "main";
} else {
userDir = userDir + separator + "testdemo" + separator + "src" + separator + "main";
}
}
// System.out.println("now:"+userDir);
return userDir;
}
然后就是压缩文件夹的过程
/**
*
* 功能描述: 生成zip文件字节流
*
*/
public static byte[] getZip(String filePath){
System.out.println("开始zip所在目录:"+filePath);
try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream)){
//将目标文件打包成zip导出
File file = new File(filePath);
createZip(zip,file,"");
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
private static void createZip(ZipOutputStream zip, File file, String dir) {
try {
//如果当前是文件夹则进行迭代处理
if (file.isDirectory()){
File[] files = file.listFiles();
//将文件夹添加至下一级目录
zip.putNextEntry(new ZipEntry(dir+"/"));
dir = dir.length()==0?"":dir+"/";
for (int i=0;i<files.length;i++){
createZip(zip,files[i],dir+files[i].getName());
}
}else {
//当前是文件,进行打包处理
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(dir);
zip.putNextEntry(entry);
// zip.write(FileUtils.readFileToByteArray(file));
int len=0;
while ((len=bis.read())!=-1){
zip.write(len);
}
IOUtils.closeQuietly(bis);
}
}catch (Exception e){
try {
zip.flush();
zip.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
这里我之前使用的是
zip.write(FileUtils.readFileToByteArray(file));
但是生成的压缩文件格式会有错误。。。