分享

java:POI导出excel

 WindySky 2017-08-16

POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel.

下面是使用示例:

1、maven中先添加依赖项

1         <dependency>
2             <groupId>org.apache.poi</groupId>
3             <artifactId>poi</artifactId>
4             <version>3.11</version>
5         </dependency>

2、最基本的导出示例

a) 先定义一个基本的类AwbData

复制代码
 1 package com.cnblogs.yjmyzz.test.domain;
 2 
 3 public class AwbDto {
 4 
 5     public AwbDto() {
 6         super();
 7 
 8     }
 9 
10     public AwbDto(String awbNumber, String agent) {
11         super();
12         this.awbNumber = awbNumber;
13         this.agent = agent;
14     }
15 
16     /**
17      * 运单号
18      */
19     private String awbNumber;
20 
21     /**
22      * 代理人
23      */
24     private String agent;
25 
26     public String getAwbNumber() {
27         return awbNumber;
28     }
29 
30     public void setAwbNumber(String awbNumber) {
31         this.awbNumber = awbNumber;
32     }
33 
34     public String getAgent() {
35         return agent;
36     }
37 
38     public void setAgent(String agent) {
39         this.agent = agent;
40     }
41 }
复制代码

b) 伪造点数据

复制代码
 1     private List<AwbDto> getData1() {
 2         List<AwbDto> data = new ArrayList<AwbDto>();
 3         for (int i = 0; i < 1000; i++) {
 4             data.add(new AwbDto("112-" + FileUtil.leftPad(i + "", 8, '0'), "张三"));
 5         }
 6         return data;
 7     }
 8     
 9     private List<AwbDto> getData2() {
10         List<AwbDto> data = new ArrayList<AwbDto>();
11         for (int i = 0; i < 1000; i++) {
12             data.add(new AwbDto("999-" + FileUtil.leftPad(i + "", 8, '0'), "李四"));
13         }
14         return data;
15     }
复制代码

上面都是准备工作,下面才是重点:

复制代码
 1     @Test
 2     public void testExcelExport() throws Exception {
 3 
 4         // 创建excel
 5         HSSFWorkbook wb = new HSSFWorkbook();
 6 
 7         // 创建sheet
 8         HSSFSheet sheet = wb.createSheet("运单数据");
 9 
10         // 创建一行
11         HSSFRow rowTitle = sheet.createRow(0);
12 
13         // 创建标题栏样式
14         HSSFCellStyle styleTitle = wb.createCellStyle();
15         styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
16         HSSFFont fontTitle = wb.createFont();
17         // 宋体加粗
18         fontTitle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
19         fontTitle.setFontName("宋体");
20         fontTitle.setFontHeight((short) 200);
21         styleTitle.setFont(fontTitle);
22 
23         // 在行上创建1列
24         HSSFCell cellTitle = rowTitle.createCell(0);
25 
26         // 列标题及样式
27         cellTitle.setCellValue("运单号");
28         cellTitle.setCellStyle(styleTitle);
29 
30         // 在行上创建2列
31         cellTitle = rowTitle.createCell(1);
32         cellTitle.setCellValue("代理人");
33         cellTitle.setCellStyle(styleTitle);
34 
35         HSSFCellStyle styleCenter = wb.createCellStyle();
36         styleCenter.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
37 
38         // 取数据
39         List<AwbDto> data = getData1();
40 
41         for (int i = 0; i < data.size(); i++) {
42 
43             AwbDto item = data.get(i);
44             HSSFRow row = sheet.createRow(i + 1);
45 
46             HSSFCell cell = row.createCell(0);
47             cell.setCellValue(item.getAwbNumber());
48             cell.setCellStyle(styleCenter);
49 
50             cell = row.createCell(1);
51             cell.setCellValue(item.getAgent());
52             cell.setCellStyle(styleCenter);
53         }
54 
55         FileOutputStream fout = new FileOutputStream("r:/awb.xls");
56         wb.write(fout);
57         fout.close();
58         wb.close();
59 
60         System.out.println("导出完成!");
61     }
复制代码

导出后,大致是这个样子:

3、通用的Excel导出类

对于格式不太复杂的常规excel,如果每次都要写上面这一堆代码,当然有点2,已经有无私的高逼格程序猿在开源中国上奉献了自己的劳动成果,借来用一下(再次向作者表示感谢),不过这份代码年头略久,有些方法已经被现在的版本标识为过时,略微改进了一下下,贴在这里:

复制代码
  1 package com.cnblogs.yjmyzz.utils;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.IOException;
  5 import java.text.SimpleDateFormat;
  6 import java.util.Date;
  7 import java.util.LinkedHashMap;
  8 import java.util.List;
  9 import java.util.Set;
 10 import java.util.Map.Entry;
 11 import org.apache.poi.hssf.usermodel.HSSFCell;
 12 import org.apache.poi.hssf.usermodel.HSSFRow;
 13 import org.apache.poi.hssf.usermodel.HSSFSheet;
 14 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 15 import org.apache.poi.ss.usermodel.CellStyle;
 16 import org.apache.poi.ss.usermodel.Font;
 17 import org.apache.poi.ss.usermodel.IndexedColors;
 18 import org.apache.poi.ss.util.CellRangeAddress;
 19 
 20 public class ExcelUtil {
 21     private static HSSFWorkbook wb;
 22 
 23     private static CellStyle titleStyle; // 标题行样式
 24     private static Font titleFont; // 标题行字体
 25     private static CellStyle dateStyle; // 日期行样式
 26     private static Font dateFont; // 日期行字体
 27     private static CellStyle headStyle; // 表头行样式
 28     private static Font headFont; // 表头行字体
 29     private static CellStyle contentStyle; // 内容行样式
 30     private static Font contentFont; // 内容行字体
 31 
 32     /**
 33      * 导出文件
 34      * 
 35      * @param setInfo
 36      * @param outputExcelFileName
 37      * @return
 38      * @throws IOException
 39      */
 40     public static boolean export2File(ExcelExportData setInfo,
 41             String outputExcelFileName) throws Exception {
 42         return FileUtil.write(outputExcelFileName, export2ByteArray(setInfo),
 43                 true, true);
 44     }
 45 
 46     /**
 47      * 导出到byte数组
 48      * 
 49      * @param setInfo
 50      * @return
 51      * @throws Exception
 52      */
 53     public static byte[] export2ByteArray(ExcelExportData setInfo)
 54             throws Exception {
 55         return export2Stream(setInfo).toByteArray();
 56     }
 57 
 58     /**
 59      * 导出到流
 60      * 
 61      * @param setInfo
 62      * @return
 63      * @throws Exception
 64      */
 65     public static ByteArrayOutputStream export2Stream(ExcelExportData setInfo)
 66             throws Exception {
 67         init();
 68 
 69         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 70 
 71         Set<Entry<String, List<?>>> set = setInfo.getDataMap().entrySet();
 72         String[] sheetNames = new String[setInfo.getDataMap().size()];
 73         int sheetNameNum = 0;
 74         for (Entry<String, List<?>> entry : set) {
 75             sheetNames[sheetNameNum] = entry.getKey();
 76             sheetNameNum++;
 77         }
 78         HSSFSheet[] sheets = getSheets(setInfo.getDataMap().size(), sheetNames);
 79         int sheetNum = 0;
 80         for (Entry<String, List<?>> entry : set) {
 81             // Sheet
 82             List<?> objs = entry.getValue();
 83 
 84             // 标题行
 85             createTableTitleRow(setInfo, sheets, sheetNum);
 86 
 87             // 日期行
 88             createTableDateRow(setInfo, sheets, sheetNum);
 89 
 90             // 表头
 91             creatTableHeadRow(setInfo, sheets, sheetNum);
 92 
 93             // 表体
 94             String[] fieldNames = setInfo.getFieldNames().get(sheetNum);
 95 
 96             int rowNum = 3;
 97             for (Object obj : objs) {
 98                 HSSFRow contentRow = sheets[sheetNum].createRow(rowNum);
 99                 contentRow.setHeight((short) 300);
100                 HSSFCell[] cells = getCells(contentRow, setInfo.getFieldNames()
101                         .get(sheetNum).length);
102                 int cellNum = 1; // 去掉一列序号,因此从1开始
103                 if (fieldNames != null) {
104                     for (int num = 0; num < fieldNames.length; num++) {
105 
106                         Object value = ReflectionUtil.invokeGetterMethod(obj,
107                                 fieldNames[num]);
108                         cells[cellNum].setCellValue(value == null ? "" : value
109                                 .toString());
110                         cellNum++;
111                     }
112                 }
113                 rowNum++;
114             }
115             adjustColumnSize(sheets, sheetNum, fieldNames); // 自动调整列宽
116             sheetNum++;
117         }
118         wb.write(outputStream);
119         return outputStream;
120     }
121 
122     /**
123      * @Description: 初始化
124      */
125     private static void init() {
126         wb = new HSSFWorkbook();
127 
128         titleFont = wb.createFont();
129         titleStyle = wb.createCellStyle();
130         dateStyle = wb.createCellStyle();
131         dateFont = wb.createFont();
132         headStyle = wb.createCellStyle();
133         headFont = wb.createFont();
134         contentStyle = wb.createCellStyle();
135         contentFont = wb.createFont();
136 
137         initTitleCellStyle();
138         initTitleFont();
139         initDateCellStyle();
140         initDateFont();
141         initHeadCellStyle();
142         initHeadFont();
143         initContentCellStyle();
144         initContentFont();
145     }
146 
147     /**
148      * @Description: 自动调整列宽
149      */
150     private static void adjustColumnSize(HSSFSheet[] sheets, int sheetNum,
151             String[] fieldNames) {
152         for (int i = 0; i < fieldNames.length + 1; i++) {
153             sheets[sheetNum].autoSizeColumn(i, true);
154         }
155     }
156 
157     /**
158      * @Description: 创建标题行(需合并单元格)
159      */
160     private static void createTableTitleRow(ExcelExportData setInfo,
161             HSSFSheet[] sheets, int sheetNum) {
162         CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, setInfo
163                 .getFieldNames().get(sheetNum).length);
164         sheets[sheetNum].addMergedRegion(titleRange);
165         HSSFRow titleRow = sheets[sheetNum].createRow(0);
166         titleRow.setHeight((short) 800);
167         HSSFCell titleCell = titleRow.createCell(0);
168         titleCell.setCellStyle(titleStyle);
169         titleCell.setCellValue(setInfo.getTitles()[sheetNum]);
170     }
171 
172     /**
173      * @Description: 创建日期行(需合并单元格)
174      */
175     private static void createTableDateRow(ExcelExportData setInfo,
176             HSSFSheet[] sheets, int sheetNum) {
177         CellRangeAddress dateRange = new CellRangeAddress(1, 1, 0, setInfo
178                 .getFieldNames().get(sheetNum).length);
179         sheets[sheetNum].addMergedRegion(dateRange);
180         HSSFRow dateRow = sheets[sheetNum].createRow(1);
181         dateRow.setHeight((short) 350);
182         HSSFCell dateCell = dateRow.createCell(0);
183         dateCell.setCellStyle(dateStyle);
184         // dateCell.setCellValue("导出时间:" + new
185         // SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
186         // .format(new Date()));
187         dateCell.setCellValue(new SimpleDateFormat("yyyy-MM-dd")
188                 .format(new Date()));
189     }
190 
191     /**
192      * @Description: 创建表头行(需合并单元格)
193      */
194     private static void creatTableHeadRow(ExcelExportData setInfo,
195             HSSFSheet[] sheets, int sheetNum) {
196         // 表头
197         HSSFRow headRow = sheets[sheetNum].createRow(2);
198         headRow.setHeight((short) 350);
199         // 序号列
200         HSSFCell snCell = headRow.createCell(0);
201         snCell.setCellStyle(headStyle);
202         snCell.setCellValue("序号");
203         // 列头名称
204         for (int num = 1, len = setInfo.getColumnNames().get(sheetNum).length; num <= len; num++) {
205             HSSFCell headCell = headRow.createCell(num);
206             headCell.setCellStyle(headStyle);
207             headCell.setCellValue(setInfo.getColumnNames().get(sheetNum)[num - 1]);
208         }
209     }
210 
211     /**
212      * @Description: 创建所有的Sheet
213      */
214     private static HSSFSheet[] getSheets(int num, String[] names) {
215         HSSFSheet[] sheets = new HSSFSheet[num];
216         for (int i = 0; i < num; i++) {
217             sheets[i] = wb.createSheet(names[i]);
218         }
219         return sheets;
220     }
221 
222     /**
223      * @Description: 创建内容行的每一列(附加一列序号)
224      */
225     private static HSSFCell[] getCells(HSSFRow contentRow, int num) {
226         HSSFCell[] cells = new HSSFCell[num + 1];
227 
228         for (int i = 0, len = cells.length; i < len; i++) {
229             cells[i] = contentRow.createCell(i);
230             cells[i].setCellStyle(contentStyle);
231         }
232 
233         // 设置序号列值,因为出去标题行和日期行,所有-2
234         cells[0].setCellValue(contentRow.getRowNum() - 2);
235 
236         return cells;
237     }
238 
239     /**
240      * @Description: 初始化标题行样式
241      */
242     private static void initTitleCellStyle() {
243         titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
244         titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
245         titleStyle.setFont(titleFont);
246         titleStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
247     }
248 
249     /**
250      * @Description: 初始化日期行样式
251      */
252     private static void initDateCellStyle() {
253         dateStyle.setAlignment(CellStyle.ALIGN_CENTER_SELECTION);
254         dateStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
255         dateStyle.setFont(dateFont);
256         dateStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
257     }
258 
259     /**
260      * @Description: 初始化表头行样式
261      */
262     private static void initHeadCellStyle() {
263         headStyle.setAlignment(CellStyle.ALIGN_CENTER);
264         headStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
265         headStyle.setFont(headFont);
266         headStyle.setFillBackgroundColor(IndexedColors.YELLOW.index);
267         headStyle.setBorderTop(CellStyle.BORDER_MEDIUM);
268         headStyle.setBorderBottom(CellStyle.BORDER_THIN);
269         headStyle.setBorderLeft(CellStyle.BORDER_THIN);
270         headStyle.setBorderRight(CellStyle.BORDER_THIN);
271         headStyle.setTopBorderColor(IndexedColors.BLUE.index);
272         headStyle.setBottomBorderColor(IndexedColors.BLUE.index);
273         headStyle.setLeftBorderColor(IndexedColors.BLUE.index);
274         headStyle.setRightBorderColor(IndexedColors.BLUE.index);
275     }
276 
277     /**
278      * @Description: 初始化内容行样式
279      */
280     private static void initContentCellStyle() {
281         contentStyle.setAlignment(CellStyle.ALIGN_CENTER);
282         contentStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
283         contentStyle.setFont(contentFont);
284         contentStyle.setBorderTop(CellStyle.BORDER_THIN);
285         contentStyle.setBorderBottom(CellStyle.BORDER_THIN);
286         contentStyle.setBorderLeft(CellStyle.BORDER_THIN);
287         contentStyle.setBorderRight(CellStyle.BORDER_THIN);
288         contentStyle.setTopBorderColor(IndexedColors.BLUE.index);
289         contentStyle.setBottomBorderColor(IndexedColors.BLUE.index);
290         contentStyle.setLeftBorderColor(IndexedColors.BLUE.index);
291         contentStyle.setRightBorderColor(IndexedColors.BLUE.index);
292         contentStyle.setWrapText(true); // 字段换行
293     }
294 
295     /**
296      * @Description: 初始化标题行字体
297      */
298     private static void initTitleFont() {
299         titleFont.setFontName("华文楷体");
300         titleFont.setFontHeightInPoints((short) 20);
301         titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
302         titleFont.setCharSet(Font.DEFAULT_CHARSET);
303         titleFont.setColor(IndexedColors.BLUE_GREY.index);
304     }
305 
306     /**
307      * @Description: 初始化日期行字体
308      */
309     private static void initDateFont() {
310         dateFont.setFontName("隶书");
311         dateFont.setFontHeightInPoints((short) 10);
312         dateFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
313         dateFont.setCharSet(Font.DEFAULT_CHARSET);
314         dateFont.setColor(IndexedColors.BLUE_GREY.index);
315     }
316 
317     /**
318      * @Description: 初始化表头行字体
319      */
320     private static void initHeadFont() {
321         headFont.setFontName("宋体");
322         headFont.setFontHeightInPoints((short) 10);
323         headFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
324         headFont.setCharSet(Font.DEFAULT_CHARSET);
325         headFont.setColor(IndexedColors.BLUE_GREY.index);
326     }
327 
328     /**
329      * @Description: 初始化内容行字体
330      */
331     private static void initContentFont() {
332         contentFont.setFontName("宋体");
333         contentFont.setFontHeightInPoints((short) 10);
334         contentFont.setBoldweight(Font.BOLDWEIGHT_NORMAL);
335         contentFont.setCharSet(Font.DEFAULT_CHARSET);
336         contentFont.setColor(IndexedColors.BLUE_GREY.index);
337     }
338 
339     /**
340      * Excel导出数据类
341      * 
342      * @author jimmy
343      *
344      */
345     public static class ExcelExportData {
346 
347         /**
348          * 导出数据 key:String 表示每个Sheet的名称 value:List<?> 表示每个Sheet里的所有数据行
349          */
350         private LinkedHashMap<String, List<?>> dataMap;
351 
352         /**
353          * 每个Sheet里的顶部大标题
354          */
355         private String[] titles;
356 
357         /**
358          * 单个sheet里的数据列标题
359          */
360         private List<String[]> columnNames;
361 
362         /**
363          * 单个sheet里每行数据的列对应的对象属性名称
364          */
365         private List<String[]> fieldNames;
366 
367         public List<String[]> getFieldNames() {
368             return fieldNames;
369         }
370 
371         public void setFieldNames(List<String[]> fieldNames) {
372             this.fieldNames = fieldNames;
373         }
374 
375         public String[] getTitles() {
376             return titles;
377         }
378 
379         public void setTitles(String[] titles) {
380             this.titles = titles;
381         }
382 
383         public List<String[]> getColumnNames() {
384             return columnNames;
385         }
386 
387         public void setColumnNames(List<String[]> columnNames) {
388             this.columnNames = columnNames;
389         }
390 
391         public LinkedHashMap<String, List<?>> getDataMap() {
392             return dataMap;
393         }
394 
395         public void setDataMap(LinkedHashMap<String, List<?>> dataMap) {
396             this.dataMap = dataMap;
397         }
398 
399     }
400 }
复制代码

里面提供了3个方法,可用于导出到文件、byte数组、以及流,其中有一个反射工具类:

复制代码
  1 package com.cnblogs.yjmyzz.utils;
  2 
  3 import java.lang.reflect.Field;
  4 import java.lang.reflect.InvocationTargetException;
  5 import java.lang.reflect.Method;
  6 import java.lang.reflect.Modifier;
  7 import java.lang.reflect.ParameterizedType;
  8 import java.lang.reflect.Type;
  9 import java.util.ArrayList;
 10 import java.util.Collection;
 11 import java.util.Date;
 12 import java.util.List;
 13 
 14 import org.apache.commons.beanutils.BeanUtils;
 15 import org.apache.commons.beanutils.ConvertUtils;
 16 import org.apache.commons.beanutils.PropertyUtils;
 17 import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
 18 import org.apache.commons.lang.StringUtils;
 19 import org.apache.commons.logging.Log;
 20 import org.apache.commons.logging.LogFactory;
 21 import org.springframework.util.Assert;
 22 
 23 /**
 24  * 反射工具类.
 25  * 
 26  * 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数.
 27  * 
 28  */
 29 
 30 public class ReflectionUtil {
 31 
 32     private static Log logger = LogFactory.getLog(ReflectionUtil.class);
 33 
 34     static {
 35         DateLocaleConverter dc = new DateLocaleConverter();
 36         // dc.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" });
 37         ConvertUtils.register(dc, Date.class);
 38     }
 39 
 40     /**
 41      * 调用Getter方法.
 42      */
 43     public static Object invokeGetterMethod(Object target, String propertyName) {
 44         String getterMethodName = "get" + StringUtils.capitalize(propertyName);
 45         return invokeMethod(target, getterMethodName, new Class[] {},
 46                 new Object[] {});
 47     }
 48 
 49     /**
 50      * 调用Setter方法.使用value的Class来查找Setter方法.
 51      */
 52     public static void invokeSetterMethod(Object target, String propertyName,
 53             Object value) {
 54         invokeSetterMethod(target, propertyName, value, null);
 55     }
 56 
 57     /**
 58      * 调用Setter方法.
 59      * 
 60      * @param propertyType
 61      *            用于查找Setter方法,为空时使用value的Class替代.
 62      */
 63     public static void invokeSetterMethod(Object target, String propertyName,
 64             Object value, Class<?> propertyType) {
 65         Class<?> type = propertyType != null ? propertyType : value.getClass();
 66         String setterMethodName = "set" + StringUtils.capitalize(propertyName);
 67         invokeMethod(target, setterMethodName, new Class[] { type },
 68                 new Object[] { value });
 69     }
 70 
 71     /**
 72      * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
 73      */
 74     public static Object getFieldValue(final Object object,
 75             final String fieldName) {
 76         Field field = getDeclaredField(object, fieldName);
 77 
 78         if (field == null) {
 79             throw new IllegalArgumentException("Could not find field ["
 80                     + fieldName + "] on target [" + object + "]");
 81         }
 82 
 83         makeAccessible(field);
 84 
 85         Object result = null;
 86         try {
 87             result = field.get(object);
 88         } catch (IllegalAccessException e) {
 89             logger.error("不可能抛出的异常{}" + e.getMessage());
 90         }
 91         return result;
 92     }
 93 
 94     /**
 95      * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
 96      */
 97     public static void setFieldValue(final Object object,
 98             final String fieldName, final Object value) {
 99         Field field = getDeclaredField(object, fieldName);
100 
101         if (field == null) {
102             throw new IllegalArgumentException("Could not find field ["
103                     + fieldName + "] on target [" + object + "]");
104         }
105 
106         makeAccessible(field);
107 
108         try {
109             field.set(object, value);
110         } catch (IllegalAccessException e) {
111             logger.error("不可能抛出的异常:{}" + e.getMessage());
112         }
113     }
114 
115     /**
116      * 直接调用对象方法, 无视private/protected修饰符.
117      */
118     public static Object invokeMethod(final Object object,
119             final String methodName, final Class<?>[] parameterTypes,
120             final Object[] parameters) {
121         Method method = getDeclaredMethod(object, methodName, parameterTypes);
122         if (method == null) {
123             throw new IllegalArgumentException("Could not find method ["
124                     + methodName + "] parameterType " + parameterTypes
125                     + " on target [" + object + "]");
126         }
127 
128         method.setAccessible(true);
129 
130         try {
131             return method.invoke(object, parameters);
132         } catch (Exception e) {
133             throw convertReflectionExceptionToUnchecked(e);
134         }
135     }
136 
137     /**
138      * 循环向上转型, 获取对象的DeclaredField.
139      * 
140      * 如向上转型到Object仍无法找到, 返回null.
141      */
142     protected static Field getDeclaredField(final Object object,
143             final String fieldName) {
144         Assert.notNull(object, "object不能为空");
145         Assert.hasText(fieldName, "fieldName");
146         for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
147                 .getSuperclass()) {
148             try {
149                 return superClass.getDeclaredField(fieldName);
150             } catch (NoSuchFieldException e) {// NOSONAR
151                                                 // Field不在当前类定义,继续向上转型
152             }
153         }
154         return null;
155     }
156 
157     /**
158      * 强行设置Field可访问.
159      */
160     protected static void makeAccessible(final Field field) {
161         if (!Modifier.isPublic(field.getModifiers())
162                 || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
163             field.setAccessible(true);
164         }
165     }
166 
167     /**
168      * 循环向上转型, 获取对象的DeclaredMethod.
169      * 
170      * 如向上转型到Object仍无法找到, 返回null.
171      */
172     protected static Method getDeclaredMethod(Object object, String methodName,
173             Class<?>[] parameterTypes) {
174         Assert.notNull(object, "object不能为空");
175 
176         for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
177                 .getSuperclass()) {
178             try {
179                 return superClass.getDeclaredMethod(methodName, parameterTypes);
180             } catch (NoSuchMethodException e) {// NOSONAR
181                                                 // Method不在当前类定义,继续向上转型
182             }
183         }
184         return null;
185     }
186 
187     /**
188      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class. eg. public UserDao
189      * extends HibernateDao<User>
190      * 
191      * @param clazz
192      *            The class to introspect
193      * @return the first generic declaration, or Object.class if cannot be
194      *         determined
195      */
196     @SuppressWarnings("unchecked")
197     public static <T> Class<T> getSuperClassGenricType(final Class<?> clazz) {
198         return getSuperClassGenricType(clazz, 0);
199     }
200 
201     /**
202      * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
203      * 
204      * 如public UserDao extends HibernateDao<User,Long>
205      * 
206      * @param clazz
207      *            clazz The class to introspect
208      * @param index
209      *            the Index of the generic ddeclaration,start from 0.
210      * @return the index generic declaration, or Object.class if cannot be
211      *         determined
212      */
213     @SuppressWarnings("unchecked")
214     public static Class getSuperClassGenricType(final Class<?> clazz,
215             final int index) {
216         Type genType = clazz.getGenericSuperclass();
217 
218         if (!(genType instanceof ParameterizedType)) {
219             logger.warn(clazz.getSimpleName()
220                     + "'s superclass not ParameterizedType");
221             return Object.class;
222         }
223 
224         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
225 
226         if (index >= params.length || index < 0) {
227             logger.warn("Index: " + index + ", Size of "
228                     + clazz.getSimpleName() + "'s Parameterized Type: "
229                     + params.length);
230             return Object.class;
231         }
232         if (!(params[index] instanceof Class)) {
233             logger.warn(clazz.getSimpleName()
234                     + " not set the actual class on superclass generic parameter");
235             return Object.class;
236         }
237 
238         return (Class) params[index];
239     }
240 
241     /**
242      * 提取集合中的对象的属性(通过getter函数), 组合成List.
243      * 
244      * @param collection
245      *            来源集合.
246      * @param propertyName
247      *            要提取的属性名.
248      */
249 
250     public static List convertElementPropertyToList(
251             final Collection collection, final String propertyName) {
252         List list = new ArrayList();
253 
254         try {
255             for (Object obj : collection) {
256                 list.add(PropertyUtils.getProperty(obj, propertyName));
257             }
258         } catch (Exception e) {
259             throw convertReflectionExceptionToUnchecked(e);
260         }
261 
262         return list;
263     }
264 
265     /**
266      * 提取集合中的对象的属性(通过getter函数), 组合成由分割符分隔的字符串.
267      * 
268      * @param collection
269      *            来源集合.
270      * @param propertyName
271      *            要提取的属性名.
272      * @param separator
273      *            分隔符.
274      */
275     @SuppressWarnings("unchecked")
276     public static String convertElementPropertyToString(
277             final Collection collection, final String propertyName,
278             final String separator) {
279         List list = convertElementPropertyToList(collection, propertyName);
280         return StringUtils.join(list, separator);
281     }
282 
283     /**
284      * 转换字符串到相应类型.
285      * 
286      * @param value
287      *            待转换的字符串
288      * @param toType
289      *            转换目标类型
290      */
291     @SuppressWarnings("unchecked")
292     public static <T> T convertStringToObject(String value, Class<T> toType) {
293         try {
294             return (T) ConvertUtils.convert(value, toType);
295         } catch (Exception e) {
296             throw convertReflectionExceptionToUnchecked(e);
297         }
298     }
299 
300     /**
301      * 将反射时的checked exception转换为unchecked exception.
302      */
303     public static RuntimeException convertReflectionExceptionToUnchecked(
304             Exception e) {
305         return convertReflectionExceptionToUnchecked(null, e);
306     }
307 
308     public static RuntimeException convertReflectionExceptionToUnchecked(
309             String desc, Exception e) {
310         desc = (desc == null) ? "Unexpected Checked Exception." : desc;
311         if (e instanceof IllegalAccessException
312                 || e instanceof IllegalArgumentException
313                 || e instanceof NoSuchMethodException) {
314             return new IllegalArgumentException(desc, e);
315         } else if (e instanceof InvocationTargetException) {
316             return new RuntimeException(desc,
317                     ((InvocationTargetException) e).getTargetException());
318         } else if (e instanceof RuntimeException) {
319             return (RuntimeException) e;
320         }
321         return new RuntimeException(desc, e);
322     }
323 
324     public static final <T> T getNewInstance(Class<T> cls) {
325         try {
326             return cls.newInstance();
327         } catch (InstantiationException e) {
328             e.printStackTrace();
329         } catch (IllegalAccessException e) {
330             e.printStackTrace();
331         }
332         return null;
333     }
334 
335     /**
336      * 拷贝 source 指定的porperties 属性 到 dest中
337      * 
338      * @return void
339      * @throws InvocationTargetException
340      * @throws IllegalAccessException
341      */
342     public static void copyPorperties(Object dest, Object source,
343             String[] porperties) throws InvocationTargetException,
344             IllegalAccessException {
345         for (String por : porperties) {
346             Object srcObj = invokeGetterMethod(source, por);
347             logger.debug("属性名:" + por + "------------- 属性值:" + srcObj);
348             if (srcObj != null) {
349                 try {
350                     BeanUtils.setProperty(dest, por, srcObj);
351                 } catch (IllegalArgumentException e) {
352                     e.printStackTrace();
353                 } catch (IllegalAccessException e) {
354                     throw e;
355                 } catch (InvocationTargetException e) {
356                     throw e;
357                 }
358             }
359         }
360     }
361 
362     /**
363      * 两者属性名一致时,拷贝source里的属性到dest里
364      * 
365      * @return void
366      * @throws IllegalAccessException
367      * @throws InvocationTargetException
368      */
369 
370     public static void copyPorperties(Object dest, Object source)
371             throws IllegalAccessException, InvocationTargetException {
372         Class<? extends Object> srcCla = source.getClass();
373         Field[] fsF = srcCla.getDeclaredFields();
374 
375         for (Field s : fsF) {
376             String name = s.getName();
377             Object srcObj = invokeGetterMethod(source, name);
378             try {
379                 BeanUtils.setProperty(dest, name, srcObj);
380             } catch (IllegalArgumentException e) {
381                 e.printStackTrace();
382             } catch (IllegalAccessException e) {
383                 throw e;
384             } catch (InvocationTargetException e) {
385                 throw e;
386             }
387         }
388         // BeanUtils.copyProperties(dest, orig);
389     }
390 
391     public static void main(String[] args) throws InvocationTargetException,
392             IllegalAccessException {
393         /*
394          * Document document = new Document(); document.setId(2);
395          * document.setCreateDate(new Date()); DocumentVo dcoVo = new
396          * DocumentVo(); ReflectionUtils.copyPorperties(dcoVo, document,new
397          * String[]{"id","businessName","createDate","applyName","docTitle",
398          * "transactStatus"}); System.out.println(dcoVo.getId());
399          */
400     }
401 }
复制代码

此外,导出到文件时,还用到了一个读写文件的工具类:

View Code

最后是调用示例:

View Code

导出后的样子如下:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约