优化代码实现
This commit is contained in:
parent
fb9e72365f
commit
e719a6e055
@ -4,5 +4,4 @@
|
|||||||
1. poi的导入导出 支持多sheet导出,详见代码 ExcelKit
|
1. poi的导入导出 支持多sheet导出,详见代码 ExcelKit
|
||||||
2. 非poi导出,导出数据量理论无上限;导出数据类型不限制List<T>(JDK8+),
|
2. 非poi导出,导出数据量理论无上限;导出数据类型不限制List<T>(JDK8+),
|
||||||
如果是jdk7及以下版本,未做支持(需要修改部分代码)
|
如果是jdk7及以下版本,未做支持(需要修改部分代码)
|
||||||
3、支持excel压缩导出节约网络资源
|
3. 支持excel压缩导出节约网络资源
|
||||||
|
|
8
pom.xml
8
pom.xml
@ -33,10 +33,18 @@
|
|||||||
<artifactId>poi-ooxml</artifactId>
|
<artifactId>poi-ooxml</artifactId>
|
||||||
<version>3.17</version>
|
<version>3.17</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redkale</groupId>
|
||||||
|
<artifactId>redkale</artifactId>
|
||||||
|
<version>1.9.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.tomcat</groupId>
|
<groupId>org.apache.tomcat</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
<version>6.0.37</version>
|
<version>6.0.37</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
@ -1,41 +1,36 @@
|
|||||||
package excel;
|
package excel;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import java.io.File;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import java.io.FileOutputStream;
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by liangxianyou at 2018/6/27 16:15.
|
* Created by liangxianyou at 2018/6/27 16:15.
|
||||||
*/
|
*/
|
||||||
public class ExcelExportKit {
|
public class ExcelExportKit {
|
||||||
|
public static final ThreadLocal<SimpleDateFormat> SDF_THREADLOCAL = new ThreadLocal<>();
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------非poi导出---------------
|
//-------------非poi导出---------------
|
||||||
private static <T> String exportExcel(Map<String, String> head, List<T> rows, BiFunction fun) {
|
public static <T,U,R> StringBuilder exportExcel(Map<String, String> head, List<T> rows, BiFunction<T,U,R> fun) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuilder buf = new StringBuilder();
|
||||||
buf.append(EXCEL_HEAD);
|
buf.append(EXCEL_HEAD);
|
||||||
buf.append(createBody(head, rows, fun));//body
|
buf.append(createBody(head, rows, fun));//body
|
||||||
buf.append(EXCEL_END);
|
buf.append(EXCEL_END);
|
||||||
|
|
||||||
System.out.println(String.format("数据:%s条,耗时:%s ms", rows.size(), System.currentTimeMillis() - start));
|
System.out.println(String.format("数据:%s条,耗时:%s ms", rows.size(), System.currentTimeMillis() - start));
|
||||||
return buf.toString();
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> StringBuffer createBody(Map<String, String> head, List<T> rows, BiFunction fun) {
|
private static <T,U,R> StringBuilder createBody(Map<String, String> head, List<T> rows, BiFunction<T,U,R> fun) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuilder buf = new StringBuilder();
|
||||||
//table-head
|
//table-head
|
||||||
buf.append("<Row ss:StyleID=\"s50\" ss:Height=\"16\">");
|
buf.append("<Row ss:StyleID=\"s50\" ss:Height=\"16\">");
|
||||||
head.forEach((k,v)->{
|
head.forEach((k,v)->{
|
||||||
@ -47,13 +42,18 @@ public class ExcelExportKit {
|
|||||||
rows.forEach(x->{
|
rows.forEach(x->{
|
||||||
buf.append("<Row>");
|
buf.append("<Row>");
|
||||||
head.forEach((k,v)->{
|
head.forEach((k,v)->{
|
||||||
Object value = fun.apply(x, v);
|
Object value = fun.apply(x, (U)v);
|
||||||
|
if (value == null) value = "";
|
||||||
if (value instanceof Number){
|
if (value instanceof Number){
|
||||||
buf.append("<Cell><Data ss:Type=\"Number\">"+value+"</Data> </Cell>");
|
buf.append("<Cell><Data ss:Type=\"Number\">"+value+"</Data> </Cell>");
|
||||||
}else if (value instanceof Date){
|
}else if (value instanceof Date){
|
||||||
buf.append("<Cell><Data ss:Type=\"Date\">"+
|
SimpleDateFormat dateFormat = SDF_THREADLOCAL.get();
|
||||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value) +
|
if (dateFormat == null) {//ThreadLocal 存贮 simpleDateFormat 对象
|
||||||
"</Data> </Cell>"
|
SDF_THREADLOCAL.set(dateFormat = new SimpleDateFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append(
|
||||||
|
"<Cell><Data ss:Type=\"String\">"+ dateFormat.format(value) +"</Data> </Cell>"
|
||||||
);
|
);
|
||||||
}else {
|
}else {
|
||||||
buf.append("<Cell><Data ss:Type=\"String\">"+value+"</Data> </Cell>");
|
buf.append("<Cell><Data ss:Type=\"String\">"+value+"</Data> </Cell>");
|
||||||
@ -65,69 +65,10 @@ public class ExcelExportKit {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void exportExcel(Map<String,String> head, List<T> rows, File file, BiFunction fun) throws IOException {
|
public static <T,U,R> void exportExceltoFile(Map<String,String> head, List<T> rows, File file, BiFunction<T,U,R> fun) throws IOException {
|
||||||
strToFile(exportExcel(head, rows, fun), file);
|
StringBuilder buf = exportExcel(head, rows, fun);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
strToFile(buf.toString(), file);
|
||||||
* excel 压缩导出
|
|
||||||
* @param head
|
|
||||||
* @param rows
|
|
||||||
* @param file
|
|
||||||
* @param fun
|
|
||||||
* @param <T>
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static <T> void exportExcelZip(Map<String,String> head, List<T> rows, File file, BiFunction fun) throws IOException {
|
|
||||||
|
|
||||||
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file));
|
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(zos);
|
|
||||||
|
|
||||||
ZipEntry zipEntry = new ZipEntry(file.getName().split("[.]")[0]+".xls");
|
|
||||||
zos.putNextEntry(zipEntry);
|
|
||||||
|
|
||||||
bos.write(exportExcel(head, rows, fun).getBytes());
|
|
||||||
bos.flush();
|
|
||||||
|
|
||||||
bos.close();
|
|
||||||
zos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
//使用redkale框架情况下的 导出
|
|
||||||
public static <T> boolean exportExcel(Map head, List<T> rows, HttpResponse response, String xlsName, BiFunction fun) throws IOException {
|
|
||||||
|
|
||||||
xlsName = new String(xlsName.getBytes("utf-8"),"iso-8859-1")+ ".xls";
|
|
||||||
response.setContentType("application/vnd.ms-excel");
|
|
||||||
response.setHeader("Content-disposition", "attachment;filename="+xlsName);
|
|
||||||
|
|
||||||
response.finish(exportExcel(head, rows, fun).getBytes());
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非poi导出excel--【javax.servlet】
|
|
||||||
* @param head 表头
|
|
||||||
* @param rows 数据
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @param xlsName 导出的文件名称
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static <T> boolean exportExcel(Map head, List<T> rows, HttpServletRequest request, HttpServletResponse response, String xlsName, BiFunction fun) throws IOException {
|
|
||||||
if(request.getHeader("user-agent") != null && request.getHeader("user-agent").indexOf("MSIE") != -1) {
|
|
||||||
xlsName = java.net.URLEncoder.encode(xlsName,"utf-8") + ".xls";
|
|
||||||
} else {
|
|
||||||
xlsName = new String(xlsName.getBytes("utf-8"),"iso-8859-1")+ ".xls";
|
|
||||||
}
|
|
||||||
OutputStream os = response.getOutputStream();
|
|
||||||
response.setContentType("application/vnd.ms-excel");
|
|
||||||
response.setHeader("Content-disposition", "attachment;filename="+xlsName);
|
|
||||||
|
|
||||||
os.write(exportExcel(head, rows, fun).getBytes());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void strToFile(String entityBody, File file) throws IOException {
|
public static void strToFile(String entityBody, File file) throws IOException {
|
||||||
@ -141,7 +82,6 @@ public class ExcelExportKit {
|
|||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class TC {
|
public static class TC {
|
||||||
public static final BiFunction BEAN = (t,u)->{
|
public static final BiFunction BEAN = (t,u)->{
|
||||||
Field field = null;
|
Field field = null;
|
||||||
|
168
test/excel/ExportKitTest.java
Normal file
168
test/excel/ExportKitTest.java
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
package excel;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.redkale.net.http.HttpResponse;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以下均为非poi导出使用示例
|
||||||
|
* 1、导出List<javabean>示例
|
||||||
|
* 2、导出List<Map> 示例
|
||||||
|
* 3、javax.servlet web项目中开发使用示例
|
||||||
|
* 4、导出压缩的excel示例
|
||||||
|
* 5、redkale web项目导出示例
|
||||||
|
*
|
||||||
|
* Created by liangxianyou at 2018/7/6 10:29.
|
||||||
|
*/
|
||||||
|
public class ExportKitTest {
|
||||||
|
|
||||||
|
//1、导出List<javabean>示例
|
||||||
|
@Test
|
||||||
|
public void exportBean(){
|
||||||
|
Map<String, String> heads = new LinkedHashMap();
|
||||||
|
heads.put("姓名", "name");
|
||||||
|
heads.put("年龄", "age");
|
||||||
|
heads.put("生日", "bir");
|
||||||
|
|
||||||
|
int total = 5_0000;
|
||||||
|
List rows = new ArrayList<>(total);
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
String name = UUID.randomUUID().toString();
|
||||||
|
int age = random.nextInt(100);
|
||||||
|
rows.add(new Person(name, age, new Date()));
|
||||||
|
}
|
||||||
|
File file = new File("target/user.xls");
|
||||||
|
if (file.exists()) file.delete();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ExcelExportKit.exportExceltoFile(heads, rows, file, ExcelExportKit.TC.BEAN);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2、导出List<Map> 示例
|
||||||
|
@Test
|
||||||
|
public void exportMapToZip(){
|
||||||
|
|
||||||
|
Map<String, String> heads = new LinkedHashMap();
|
||||||
|
heads.put("姓名", "name");
|
||||||
|
heads.put("姓名1", "name1");
|
||||||
|
heads.put("姓名2", "name2");
|
||||||
|
heads.put("年龄", "age");
|
||||||
|
|
||||||
|
int total = 5_0000;
|
||||||
|
List<Map> rows = new ArrayList<>(total);
|
||||||
|
|
||||||
|
Map r1 = new HashMap();
|
||||||
|
r1.put("name", "张三");
|
||||||
|
r1.put("age", 12);
|
||||||
|
rows.add(r1);
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
//使用uuid 模拟复杂数据导出
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
Map r2 = new HashMap();
|
||||||
|
r2.put("name", UUID.randomUUID());
|
||||||
|
r2.put("name1", UUID.randomUUID());
|
||||||
|
r2.put("name2", UUID.randomUUID());
|
||||||
|
r2.put("age", random.nextInt(100));
|
||||||
|
rows.add(r2);
|
||||||
|
}
|
||||||
|
File file = new File("target/hello.zip");
|
||||||
|
if (file.exists()) file.delete();
|
||||||
|
|
||||||
|
try {
|
||||||
|
exportExcelZip(heads, rows, file, ExcelExportKit.TC.MAP);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================项目中使用示例,实际项目根据实际情况拷贝修改使用========================
|
||||||
|
/**
|
||||||
|
* 3、javax.servlet web项目中开发使用示例
|
||||||
|
* @param head 表头
|
||||||
|
* @param rows 数据
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param xlsName 导出的文件名称
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public <T> boolean exportExcel(Map head, List<T> rows, HttpServletRequest request, HttpServletResponse response, String xlsName, BiFunction fun) throws IOException {
|
||||||
|
if(request.getHeader("user-agent") != null && request.getHeader("user-agent").indexOf("MSIE") != -1) {
|
||||||
|
xlsName = java.net.URLEncoder.encode(xlsName,"utf-8") + ".xls";
|
||||||
|
} else {
|
||||||
|
xlsName = new String(xlsName.getBytes("utf-8"),"iso-8859-1")+ ".xls";
|
||||||
|
}
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(187);
|
||||||
|
|
||||||
|
|
||||||
|
latch.countDown();
|
||||||
|
|
||||||
|
OutputStream os = response.getOutputStream();
|
||||||
|
response.setContentType("application/vnd.ms-excel");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename="+xlsName);
|
||||||
|
|
||||||
|
os.write(ExcelExportKit.exportExcel(head, rows, fun).toString().getBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4、导出压缩的excel示例
|
||||||
|
* @param head
|
||||||
|
* @param rows
|
||||||
|
* @param file
|
||||||
|
* @param fun
|
||||||
|
* @param <T>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public <T,U,R> void exportExcelZip(Map<String,String> head, List<T> rows, File file, BiFunction<T, U, R> fun) throws IOException {
|
||||||
|
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file));
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(zos);
|
||||||
|
|
||||||
|
ZipEntry zipEntry = new ZipEntry(file.getName().split("[.]")[0]+".xls");
|
||||||
|
zos.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
StringBuilder buf = ExcelExportKit.exportExcel(head, rows, fun);
|
||||||
|
bos.write(buf.toString().getBytes());
|
||||||
|
bos.flush();
|
||||||
|
|
||||||
|
bos.close();
|
||||||
|
zos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5、redkale web项目导出示例
|
||||||
|
* @param head
|
||||||
|
* @param rows
|
||||||
|
* @param response
|
||||||
|
* @param xlsName
|
||||||
|
* @param fun
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static <T,U,R> void exportExcel(Map head, List<T> rows, HttpResponse response, String xlsName, BiFunction<T,U,R> fun) throws IOException {
|
||||||
|
|
||||||
|
xlsName = new String(xlsName.getBytes("utf-8"),"iso-8859-1")+ ".xls";
|
||||||
|
response.setContentType("application/vnd.ms-excel");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename="+xlsName);
|
||||||
|
|
||||||
|
StringBuilder buf = ExcelExportKit.exportExcel(head, rows, fun);
|
||||||
|
response.finish(buf.toString().getBytes());
|
||||||
|
}
|
||||||
|
}
|
@ -1,76 +0,0 @@
|
|||||||
package excel;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by liangxianyou at 2018/7/6 10:29.
|
|
||||||
*/
|
|
||||||
public class ExportTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void exportBean(){
|
|
||||||
Map<String, String> heads = new LinkedHashMap();
|
|
||||||
heads.put("姓名", "name");
|
|
||||||
heads.put("年龄", "age");
|
|
||||||
|
|
||||||
int total = 5_0000;
|
|
||||||
List rows = new ArrayList<>(total);
|
|
||||||
Random random = new Random();
|
|
||||||
|
|
||||||
for (int i = 0; i < total; i++) {
|
|
||||||
String name = UUID.randomUUID().toString();
|
|
||||||
int age = random.nextInt(100);
|
|
||||||
rows.add(new Person(name, age));
|
|
||||||
}
|
|
||||||
File file = new File("target/user.zip");
|
|
||||||
if (file.exists()) file.delete();
|
|
||||||
|
|
||||||
try {
|
|
||||||
ExcelExportKit.exportExcelZip(heads, rows, file, ExcelExportKit.TC.BEAN);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void exportMapToZip(){
|
|
||||||
|
|
||||||
Map<String, String> heads = new LinkedHashMap();
|
|
||||||
heads.put("姓名", "name");
|
|
||||||
heads.put("姓名1", "name1");
|
|
||||||
heads.put("姓名2", "name2");
|
|
||||||
heads.put("年龄", "age");
|
|
||||||
|
|
||||||
int total = 5_0000;
|
|
||||||
List<Map> rows = new ArrayList<>(total);
|
|
||||||
|
|
||||||
Map r1 = new HashMap();
|
|
||||||
r1.put("name", "张三");
|
|
||||||
r1.put("age", 12);
|
|
||||||
rows.add(r1);
|
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
|
|
||||||
//使用uuid 模拟复杂数据导出
|
|
||||||
for (int i = 0; i < total; i++) {
|
|
||||||
Map r2 = new HashMap();
|
|
||||||
r2.put("name", UUID.randomUUID());
|
|
||||||
r2.put("name1", UUID.randomUUID());
|
|
||||||
r2.put("name2", UUID.randomUUID());
|
|
||||||
r2.put("age", random.nextInt(100));
|
|
||||||
rows.add(r2);
|
|
||||||
}
|
|
||||||
File file = new File("target/hello.zip");
|
|
||||||
if (file.exists()) file.delete();
|
|
||||||
|
|
||||||
try {
|
|
||||||
ExcelExportKit.exportExcelZip(heads, rows, file, ExcelExportKit.TC.MAP);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +1,22 @@
|
|||||||
package excel;
|
package excel;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by liangxianyou at 2018/7/6 10:28.
|
* Created by liangxianyou at 2018/7/6 10:28.
|
||||||
*/
|
*/
|
||||||
public class Person {
|
public class Person {
|
||||||
private String name;
|
private String name;
|
||||||
private int age;
|
private int age;
|
||||||
|
private Date bir;
|
||||||
|
|
||||||
public Person() {
|
public Person() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Person(String name, int age) {
|
public Person(String name, int age, Date bir) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.age = age;
|
this.age = age;
|
||||||
|
this.bir = bir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -30,4 +34,12 @@ public class Person {
|
|||||||
public void setAge(int age) {
|
public void setAge(int age) {
|
||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getBir() {
|
||||||
|
return bir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBir(Date bir) {
|
||||||
|
this.bir = bir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user