POI是一個開源項目,專用于java平臺上操作MS OFFICE,企業(yè)應(yīng)用開發(fā)中可用它方便導(dǎo)出Excel.
下面是使用示例:
1、maven中先添加依賴項
1 <dependency>2 <groupId>org.apache.poi</groupId>3 <artifactId>poi</artifactId>4 <version>3.11</version>5 </dependency>
2、最基本的導(dǎo)出示例
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) 偽造點數(shù)據(jù)
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 }
上面都是準(zhǔn)備工作,下面才是重點:
1 @Test 2 public void testExcelExport() throws Exception { 3 4 // 創(chuàng)建excel 5 HSSFWorkbook wb = new HSSFWorkbook(); 6 7 // 創(chuàng)建sheet 8 HSSFSheet sheet = wb.createSheet("運單數(shù)據(jù)"); 9 10 // 創(chuàng)建一行11 HSSFRow rowTitle = sheet.createRow(0);12 13 // 創(chuàng)建標(biāo)題欄樣式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 // 在行上創(chuàng)建1列24 HSSFCell cellTitle = rowTitle.createCell(0);25 26 // 列標(biāo)題及樣式27 cellTitle.setCellValue("運單號");28 cellTitle.setCellStyle(styleTitle);29 30 // 在行上創(chuàng)建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 // 取數(shù)據(jù)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("導(dǎo)出完成!");61 }
導(dǎo)出后,大致是這個樣子:
3、通用的Excel導(dǎo)出類
對于格式不太復(fù)雜的常規(guī)excel,如果每次都要寫上面這一堆代碼,當(dāng)然有點2,已經(jīng)有無私的高逼格程序猿在開源中國上奉獻了自己的勞動成果,借來用一下(再次向作者表示感謝),不過這份代碼年頭略久,有些方法已經(jīng)被現(xiàn)在的版本標(biāo)識為過時,略微改進了一下下,貼在這里:
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; // 標(biāo)題行樣式 24 private static Font titleFont; // 標(biāo)題行字體 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; // 內(nèi)容行樣式 30 private static Font contentFont; // 內(nèi)容行字體 31 32 /** 33 * 導(dǎo)出文件 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 * 導(dǎo)出到byte數(shù)組 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 * 導(dǎo)出到流 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 // 標(biāo)題行 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 ? "" : value109 .toString());110 cellNum++;111 }112 }113 rowNum++;114 }115 adjustColumnSize(sheets, sheetNum, fieldNames); // 自動調(diào)整列寬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: 自動調(diào)整列寬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: 創(chuàng)建標(biāo)題行(需合并單元格)159 */160 private static void createTableTitleRow(ExcelExportData setInfo,161 HSSFSheet[] sheets, int sheetNum) {162 CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, setInfo163 .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: 創(chuàng)建日期行(需合并單元格)174 */175 private static void createTableDateRow(ExcelExportData setInfo,176 HSSFSheet[] sheets, int sheetNum) {177 CellRangeAddress dateRange = new CellRangeAddress(1, 1, 0, setInfo178 .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("導(dǎo)出時間:" + new185 // 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: 創(chuàng)建表頭行(需合并單元格)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: 創(chuàng)建所有的Sheet213 */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: 創(chuàng)建內(nèi)容行的每一列(附加一列序號)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 // 設(shè)置序號列值,因為出去標(biāo)題行和日期行,所有-2234 cells[0].setCellValue(contentRow.getRowNum() - 2);235 236 return cells;237 }238 239 /**240 * @Description: 初始化標(biāo)題行樣式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: 初始化內(nèi)容行樣式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: 初始化標(biāo)題行字體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: 初始化內(nèi)容行字體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導(dǎo)出數(shù)據(jù)類341 * 342 * @author jimmy343 *344 */345 public static class ExcelExportData {346 347 /**348 * 導(dǎo)出數(shù)據(jù) key:String 表示每個Sheet的名稱 value:List<?> 表示每個Sheet里的所有數(shù)據(jù)行349 */350 private LinkedHashMap<String, List<?>> dataMap;351 352 /**353 * 每個Sheet里的頂部大標(biāo)題354 */355 private String[] titles;356 357 /**358 * 單個sheet里的數(shù)據(jù)列標(biāo)題359 */360 private List<String[]> columnNames;361 362 /**363 * 單個sheet里每行數(shù)據(jù)的列對應(yīng)的對象屬性名稱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個方法,可用于導(dǎo)出到文件、byte數(shù)組、以及流,其中有一個反射工具類:
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, 提取集合中元素的屬性, 轉(zhuǎn)換字符串到對象等Util函數(shù). 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 * 調(diào)用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 * 調(diào)用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 * 調(diào)用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修飾符, 不經(jīng)過getter函數(shù). 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 * 直接設(shè)置對象屬性值, 無視private/protected修飾符, 不經(jīng)過setter函數(shù). 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 * 直接調(diào)用對象方法, 無視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 " + parameterTypes125 + " 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 * 循環(huán)向上轉(zhuǎn)型, 獲取對象的DeclaredField.139 * 140 * 如向上轉(zhuǎn)型到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 = superClass147 .getSuperclass()) {148 try {149 return superClass.getDeclaredField(fieldName);150 } catch (NoSuchFieldException e) {// NOSONAR151 // Field不在當(dāng)前類定義,繼續(xù)向上轉(zhuǎn)型152 }153 }154 return null;155 }156 157 /**158 * 強行設(shè)置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 * 循環(huán)向上轉(zhuǎn)型, 獲取對象的DeclaredMethod.169 * 170 * 如向上轉(zhuǎn)型到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 = superClass177 .getSuperclass()) {178 try {179 return superClass.getDeclaredMethod(methodName, parameterTypes);180 } catch (NoSuchMethodException e) {// NOSONAR181 // Method不在當(dāng)前類定義,繼續(xù)向上轉(zhuǎn)型182 }183 }184 return null;185 }186 187 /**188 * 通過反射, 獲得Class定義中聲明的父類的泛型參數(shù)的類型. 如無法找到, 返回Object.class. eg. public UserDao189 * extends HibernateDao<User>190 * 191 * @param clazz192 * The class to introspect193 * @return the first generic declaration, or Object.class if cannot be194 * determined195 */196 @SuppressWarnings("unchecked")197 public static <T> Class<T> getSuperClassGenricType(final Class<?> clazz) {198 return getSuperClassGenricType(clazz, 0);199 }200 201 /**202 * 通過反射, 獲得定義Class時聲明的父類的泛型參數(shù)的類型. 如無法找到, 返回Object.class.203 * 204 * 如public UserDao extends HibernateDao<User,Long>205 * 206 * @param clazz207 * clazz The class to introspect208 * @param index209 * the Index of the generic ddeclaration,start from 0.210 * @return the index generic declaration, or Object.class if cannot be211 * determined212 */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函數(shù)), 組合成List.243 * 244 * @param collection245 * 來源集合.246 * @param propertyName247 * 要提取的屬性名.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函數(shù)), 組合成由分割符分隔的字符串.267 * 268 * @param collection269 * 來源集合.270 * @param propertyName271 * 要提取的屬性名.272 * @param separator273 * 分隔符.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 * 轉(zhuǎn)換字符串到相應(yīng)類型.285 * 286 * @param value287 * 待轉(zhuǎn)換的字符串288 * @param toType289 * 轉(zhuǎn)換目標(biāo)類型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轉(zhuǎn)換為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 IllegalAccessException312 || e instanceof IllegalArgumentException313 || 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 void339 * @throws InvocationTargetException340 * @throws IllegalAccessException341 */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 void366 * @throws IllegalAccessException367 * @throws InvocationTargetException368 */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 = new396 * DocumentVo(); ReflectionUtils.copyPorperties(dcoVo, document,new397 * String[]{"id","businessName","createDate","applyName","docTitle",398 * "transactStatus"}); System.out.println(dcoVo.getId());399 */400 }401 }
此外,導(dǎo)出到文件時,還用到了一個讀寫文件的工具類:
最后是調(diào)用示例:
導(dǎo)出后的樣子如下: