java 导出Excel 大数据量,自己经验总结!(二)

在上一次的基础上加上了样式,以及中文列名

  1 package com.tommy.fundation.util;
  2 
  3 import java.io.OutputStream;
  4 import java.util.ArrayList;
  5 import java.util.HashMap;
  6 import java.util.Iterator;
  7 import java.util.List;
  8 import java.util.Map;
  9 import java.util.Set;
 10 
 11 import javax.servlet.http.HttpServletResponse;
 12 
 13 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 14 import org.apache.poi.hssf.usermodel.HSSFSheet;
 15 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 16 import org.apache.poi.hssf.usermodel.HSSFFont;
 17 import org.apache.poi.hssf.usermodel.HSSFRow;
 18 import org.apache.poi.hssf.usermodel.HSSFCell;
 19 import org.apache.poi.ss.usermodel.CellStyle;
 20 import org.apache.poi.ss.usermodel.Font;
 21 import org.apache.poi.ss.usermodel.IndexedColors;
 22 
 23 public class ExportExcel<T> {
 24     public void doExcel(HttpServletResponse response, List<T> list, String fileName) throws Exception {
 25         String[] columnNames = new String[0];
 26         doExcel(response, list , columnNames, fileName);
 27     }
 28     /**
 29      * 导出多张excel表,解决xls格式行数65535的限制
 30      * @author OnlyOne
 31      * @param response
 32      * @param list 需要处理的list数据集合
 33      * @param columnNames 与实体属性一一对应的列名
 34      * @param fileName 文件名
 35      * @throws Exception
 36      */
 37     public void doExcel(HttpServletResponse response, List<T> list, String[] columnNames, String fileName) throws Exception {
 38         OutputStream os = response.getOutputStream();//获取输出流
 39         response.reset();
 40         // 设置下载头部信息。Content-disposition为属性名。attachment表示以附件方式下载,如果要在页面中打开,则改为inline。filename为文件名
 41         response.setContentType("application/vnd.ms-excel;charset=utf-8");
 42         response.setHeader("Content-disposition", "attachment;filename="+ new String((fileName + ".xls").getBytes(), "iso-8859-1"));
 43 
 44         //将数据集合按65000个进行分割成多个子集合
 45         Map<Integer, List<T>> sheetMap = doSheets(list);
 46         // 创建excel工作簿
 47         HSSFWorkbook wb = new HSSFWorkbook();
 48         //将map集合转换成set集合
 49         Set<Integer> keys = sheetMap.keySet();
 50 
 51         // 创建两种单元格格式
 52         HSSFCellStyle cs = wb.createCellStyle();
 53         HSSFCellStyle cs2 = wb.createCellStyle();
 54 
 55         // 创建两种字体
 56         HSSFFont f = wb.createFont();
 57         HSSFFont f2 = wb.createFont();
 58 
 59         // 创建第一种字体样式(用于列名)
 60         f.setFontHeightInPoints((short) 10);
 61         f.setColor(IndexedColors.BLACK.getIndex());
 62         f.setBoldweight(Font.BOLDWEIGHT_BOLD);
 63 
 64         // 创建第二种字体样式(用于值)
 65         f2.setFontHeightInPoints((short) 10);
 66         f2.setColor(IndexedColors.BLACK.getIndex());
 67 
 68         // 设置第一种单元格的样式(用于列名)
 69         cs.setFont(f);
 70         cs.setBorderLeft(CellStyle.BORDER_THIN);
 71         cs.setBorderRight(CellStyle.BORDER_THIN);
 72         cs.setBorderTop(CellStyle.BORDER_THIN);
 73         cs.setBorderBottom(CellStyle.BORDER_THIN);
 74         cs.setAlignment(CellStyle.ALIGN_CENTER);
 75 
 76         // 设置第二种单元格的样式(用于值)
 77         cs2.setFont(f2);
 78         cs2.setBorderLeft(CellStyle.BORDER_THIN);
 79         cs2.setBorderRight(CellStyle.BORDER_THIN);
 80         cs2.setBorderTop(CellStyle.BORDER_THIN);
 81         cs2.setBorderBottom(CellStyle.BORDER_THIN);
 82         cs2.setAlignment(CellStyle.ALIGN_CENTER);
 83 
 84         //对set集合进行遍历
 85         for (Iterator<Integer> iterator = keys.iterator(); iterator.hasNext();) {
 86             //获取遍历的下标
 87             Integer sheetKey = iterator.next();
 88             // 创建一个sheet(页),并命名
 89             HSSFSheet sheet = wb.createSheet("sheet"+sheetKey);
 90             //获取一页的数据
 91             List<T> sheetData = sheetMap.get(sheetKey);
 92             //创建列名的行
 93             HSSFRow firstRow = sheet.createRow(0);
 94             //如果columnNames有值,则作为列名;如果没有,则实体的属性名作为列名
 95             if(columnNames.length == 0){
 96                 T en = (T) sheetData.get(0);
 97                 List<Object> titleList = RelectUtil.<T>reflectEntityAttribute(en);
 98                 for(int m=0; m<titleList.size(); m++){
 99                     HSSFCell cell = firstRow.createCell(m);
100                     cell.setCellValue(titleList.get(m+1).toString());
101                     cell.setCellStyle(cs);
102                 }
103             }else{
104                 for(int m=0; m<columnNames.length; m++){
105                     HSSFCell cell = firstRow.createCell(m);
106                     cell.setCellValue(columnNames[m]);
107                     cell.setCellStyle(cs);
108                 }
109             }
110 
111             // 手动设置列宽。第一个参数表示要为第几列设;,第二个参数表示列的宽度,n为列高的像素数。
112             for(int i=0;i<columnNames.length;i++){
113                 sheet.setColumnWidth((short) i, (short) (35.7 * 100));
114             }
115 
116             //遍历一页的数据集合
117             for (int i = 0, len = sheetData.size(); i < len; i++) {
118                 //获取数据实体
119                 T en = (T) sheetData.get(i);
120                 //反射获取行数据
121                 List<Object> dataList = RelectUtil.<T>reflectEntity(en, en.getClass());
122                 //创建数据行,以第二行开始,第一行作为列名使用
123                 HSSFRow row = sheet.createRow(i+1);
124                 for(int m=0; m<dataList.size(); m++){
125                     HSSFCell cell = row.createCell(m);
126                     cell.setCellValue(dataList.get(m).toString());
127                     cell.setCellStyle(cs2);
128                 }
129 
130             }
131         }
132         wb.write(os);
133         os.flush();
134         os.close();
135     }
136     /**
137      * 此方法将数据集合按65000个进行分割成多个子集合
138      * @author OnlyOne
139      * @param list 需要处理的list数据集合
140      * @return
141      */
142     public Map<Integer, List<T>> doSheets(List<T> list){
143         int count = list.size()/65000;
144         int yu = list.size() % 65000;
145         Map<Integer, List<T>> map = new HashMap<Integer, List<T>>();
146         for (int i = 0; i <= count; i++) {
147             List<T> subList = new ArrayList<T>();
148             if (i == count) {
149                 subList = list.subList(i * 65000, 65000 * i + yu);
150             } else {
151                 subList = list.subList(i * 65000, 65000 * (i + 1));
152             }
153             map.put(i, subList);
154         }
155         return map;
156     }
157 }

辅助工具类

 1 package com.tommy.fundation.util;
 2 
 3 import java.lang.reflect.Field;
 4 import java.lang.reflect.InvocationTargetException;
 5 import java.lang.reflect.Method;
 6 import java.util.ArrayList;
 7 import java.util.Date;
 8 import java.util.List;
 9 
10 public class RelectUtil {
11     public static <T> List<Object> reflectEntity(T model,Class<?> cals) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchFieldException{
12         List<Object> list = new ArrayList<Object>();
13         Field[] field = model.getClass().getDeclaredFields();        //获取实体类的所有属性,返回Field数组  
14         for(int j=0 ; j<field.length ; j++){     //遍历所有属性
15             String nam = field[j].getName();    //获取属性的名字
16             String name = nam;
17             name  = name.substring(0,1).toUpperCase()+name.substring(1);
18             String type = field[j].getGenericType().toString();    //获取属性的类型
19 
20             if(type.equals("class java.lang.String")){   //如果type是类类型,则前面包含"class ",后面跟类名
21                 Method m = model.getClass().getMethod("get"+name);
22                 String value = (String) m.invoke(model);    //调用getter方法获取属性值
23                 if(value != null){
24                    list.add(value);
25                 }else{
26                     list.add("");
27                 }
28             }
29 
30             if(type.equals("class java.lang.Integer") || type.equals("int")){
31                 Method m = model.getClass().getMethod("get"+name);
32                 Integer value = (Integer) m.invoke(model);
33                 if(value != null){
34                     list.add(value);
35                 }else{
36                     list.add("");
37                 }
38             }
39 
40             if(type.equals("class java.lang.Short") || type.equals("short")){
41                 Method m = model.getClass().getMethod("get"+name);
42                 Short value = (Short) m.invoke(model);
43                 if(value != null){
44                     list.add(value);                    
45                 }else{
46                     list.add("");
47                 }
48             }       
49 
50             if(type.equals("class java.lang.Double") || type.equals("double")){
51                 Method m = model.getClass().getMethod("get"+name);
52                 Double value = (Double) m.invoke(model);
53                 if(value != null){                    
54                     list.add(value);  
55                 }else{
56                     list.add("");
57                 }
58             }                  
59 
60             if(type.equals("class java.lang.Boolean") || type.equals("boolean")){
61                 Method m = model.getClass().getMethod("get"+name);    
62                 Boolean value = (Boolean) m.invoke(model);
63                 if(value != null){                      
64                     list.add(value);
65                 }else{
66                     list.add("");
67                 }
68             }
69 
70             if(type.equals("class java.util.Date")){
71                 Method m = model.getClass().getMethod("get"+name);                    
72                 Date value = (Date) m.invoke(model);
73                 if(value != null){
74                     list.add(value);
75                 }else{
76                     list.add("");
77                 }
78             }                
79         }
80         return list;
81     }
82     public static <T> List<Object> reflectEntityAttribute(T model) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchFieldException {
83         List<Object> list = new ArrayList<Object>();
84         Field[] field = model.getClass().getDeclaredFields();        //获取实体类的所有属性,返回Field数组
85         for (int j = 0; j < field.length; j++) {     //遍历所有属性
86             String nam = field[j].getName();    //获取属性的名字
87             list.add(nam);
88         }
89         return list;
90     }
91 }
原文地址:https://www.cnblogs.com/onlymate/p/5242133.html