由于servletResponse 获取的输出流对象在一次请求中只能输出一次,所以要想实现批量导出报表,需要将excel文件打包成zip格式然后输出。
好了,废话不多说,上代码。
1. 首先,需要导入引用的包。pom文件如下所示(点击“+”号展开)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.alan.demo</groupId>
<artifactId>office2007-export</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies> <!-- Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot Maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
2. Controller 实现
package com.alan.demo.controller; import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import com.alan.demo.util.FileUtil; /**
* export batch Excel files.
*
* */
@RestController
public class DataExportController {
private static final String BASE_PATH = System.getProperty("java.io.tmpdir") + "Resource" + File.separator;
@RequestMapping(value = "/export",method = RequestMethod.GET)
public void export(HttpServletRequest request, HttpServletResponse response) {
ZipOutputStream out = null;
BufferedInputStream bis = null;
InputStream in = null;
String tip = UUID.randomUUID().toString() + File.separator;
try {
createAllWorkbooks(tip);
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + "EXCEL2016.zip");
File tempZip = new File(BASE_PATH + tip + "temp.zip");
FileUtil.createZipFile(new File(BASE_PATH+ tip), new ZipOutputStream(tempZip));
System.out.println("Created ZIP File");
OutputStream os = response.getOutputStream();
in = new FileInputStream(tempZip);
bis = new BufferedInputStream(in);
byte buff[] = new byte[1024];
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
FileUtil.deleteDir(BASE_PATH);
}
} /**
* create mock data
*
* */
public List<Workbook> createAllWorkbooks(String tip) {
List<Workbook> workbooks = new ArrayList<>();
OutputStream out = null;
try {
for (int i=0;i<100;i++) {
File tempFile = new File(BASE_PATH + tip + i + ".xlsx");
tempFile.getParentFile().mkdirs();
tempFile.createNewFile();
out = new FileOutputStream(tempFile);
Workbook workbook = new XSSFWorkbook();
workbook.createSheet("summary");
workbook.getSheetAt(0).createRow(0);
Row row = workbook.getSheetAt(0).getRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Hello Spring Boot.");
workbooks.add(workbook);
workbook.write(out);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out!= null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return workbooks;
}
}
3. FileUtil 工具类
package com.alan.demo.util; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream; import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream; public class FileUtil {
/**
* Compress all .xlsx Files under original path.
*
* */
public static void compress(File original, ZipOutputStream out) {
try {
if (original == null) {
System.err.println("Null original file is not allowed.");
}
if (!original.isFile()) {
File[] files = original.listFiles();
for (File file : files) {
compress(file, out);
}
} else if (original.isFile() && original.getName().endsWith(".xlsx")) { FileInputStream fis = new FileInputStream(original);
int j = 0;
byte[] buffer = new byte[1024];
out.putNextEntry(new ZipEntry(original.getName()));
while ((j = fis.read(buffer)) > 0) {
out.write(buffer, 0, j);
}
fis.close();
out.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* Delete all files under path.
*
* */
public static boolean deleteDir(String path){
File file = new File(path);
if(!file.exists()){
System.err.println("The dir are not exists!");
return false;
} String[] content = file.list();
for(String name : content){
File temp = new File(path, name);
if(temp.isDirectory()){
deleteDir(temp.getAbsolutePath());
temp.delete();
}else{
if(!temp.delete()){
System.err.println("Failed to delete " + name);
}
}
}
return true;
} /**
* Create zip file
* @param originalFile : the directory contains all files prepared to compress.
* @param ZipOutputStream : ZIP file out put stream
* */
public static void createZipFile(File originalFile, ZipOutputStream out) { FileUtil.compress(originalFile, out);
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* clone input stream
*
* */
public static ByteArrayOutputStream cloneInputStream(InputStream in) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len=in.read(buffer)) >0) {
out.write(buffer, 0, len);
}
out.flush();
return out;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/*public static void main(String[] args) {
deleteDir("C:\\Users\\mh\\Desktop\\TEMP");
}*/
}
测试结果: