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

下面是使用示例:

1、maven中先添加依赖项

         <dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>

2、最基本的导出示例

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

 package com.cnblogs.yjmyzz.test.domain;

 public class AwbDto {

     public AwbDto() {
super(); } public AwbDto(String awbNumber, String agent) {
super();
this.awbNumber = awbNumber;
this.agent = agent;
} /**
* 运单号
*/
private String awbNumber; /**
* 代理人
*/
private String agent; public String getAwbNumber() {
return awbNumber;
} public void setAwbNumber(String awbNumber) {
this.awbNumber = awbNumber;
} public String getAgent() {
return agent;
} public void setAgent(String agent) {
this.agent = agent;
}
}

b) 伪造点数据

     private List<AwbDto> getData1() {
List<AwbDto> data = new ArrayList<AwbDto>();
for (int i = 0; i < 1000; i++) {
data.add(new AwbDto("112-" + FileUtil.leftPad(i + "", 8, '0'), "张三"));
}
return data;
} private List<AwbDto> getData2() {
List<AwbDto> data = new ArrayList<AwbDto>();
for (int i = 0; i < 1000; i++) {
data.add(new AwbDto("999-" + FileUtil.leftPad(i + "", 8, '0'), "李四"));
}
return data;
}

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

     @Test
public void testExcelExport() throws Exception { // 创建excel
HSSFWorkbook wb = new HSSFWorkbook(); // 创建sheet
HSSFSheet sheet = wb.createSheet("运单数据"); // 创建一行
HSSFRow rowTitle = sheet.createRow(0); // 创建标题栏样式
HSSFCellStyle styleTitle = wb.createCellStyle();
styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
HSSFFont fontTitle = wb.createFont();
// 宋体加粗
fontTitle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
fontTitle.setFontName("宋体");
fontTitle.setFontHeight((short) 200);
styleTitle.setFont(fontTitle); // 在行上创建1列
HSSFCell cellTitle = rowTitle.createCell(0); // 列标题及样式
cellTitle.setCellValue("运单号");
cellTitle.setCellStyle(styleTitle); // 在行上创建2列
cellTitle = rowTitle.createCell(1);
cellTitle.setCellValue("代理人");
cellTitle.setCellStyle(styleTitle); HSSFCellStyle styleCenter = wb.createCellStyle();
styleCenter.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中 // 取数据
List<AwbDto> data = getData1(); for (int i = 0; i < data.size(); i++) { AwbDto item = data.get(i);
HSSFRow row = sheet.createRow(i + 1); HSSFCell cell = row.createCell(0);
cell.setCellValue(item.getAwbNumber());
cell.setCellStyle(styleCenter); cell = row.createCell(1);
cell.setCellValue(item.getAgent());
cell.setCellStyle(styleCenter);
} FileOutputStream fout = new FileOutputStream("r:/awb.xls");
wb.write(fout);
fout.close();
wb.close(); System.out.println("导出完成!");
}

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

3、通用的Excel导出类

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

 package com.cnblogs.yjmyzz.utils;

 import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddress; public class ExcelUtil {
private static HSSFWorkbook wb; private static CellStyle titleStyle; // 标题行样式
private static Font titleFont; // 标题行字体
private static CellStyle dateStyle; // 日期行样式
private static Font dateFont; // 日期行字体
private static CellStyle headStyle; // 表头行样式
private static Font headFont; // 表头行字体
private static CellStyle contentStyle; // 内容行样式
private static Font contentFont; // 内容行字体 /**
* 导出文件
*
* @param setInfo
* @param outputExcelFileName
* @return
* @throws IOException
*/
public static boolean export2File(ExcelExportData setInfo,
String outputExcelFileName) throws Exception {
return FileUtil.write(outputExcelFileName, export2ByteArray(setInfo),
true, true);
} /**
* 导出到byte数组
*
* @param setInfo
* @return
* @throws Exception
*/
public static byte[] export2ByteArray(ExcelExportData setInfo)
throws Exception {
return export2Stream(setInfo).toByteArray();
} /**
* 导出到流
*
* @param setInfo
* @return
* @throws Exception
*/
public static ByteArrayOutputStream export2Stream(ExcelExportData setInfo)
throws Exception {
init(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Set<Entry<String, List<?>>> set = setInfo.getDataMap().entrySet();
String[] sheetNames = new String[setInfo.getDataMap().size()];
int sheetNameNum = 0;
for (Entry<String, List<?>> entry : set) {
sheetNames[sheetNameNum] = entry.getKey();
sheetNameNum++;
}
HSSFSheet[] sheets = getSheets(setInfo.getDataMap().size(), sheetNames);
int sheetNum = 0;
for (Entry<String, List<?>> entry : set) {
// Sheet
List<?> objs = entry.getValue(); // 标题行
createTableTitleRow(setInfo, sheets, sheetNum); // 日期行
createTableDateRow(setInfo, sheets, sheetNum); // 表头
creatTableHeadRow(setInfo, sheets, sheetNum); // 表体
String[] fieldNames = setInfo.getFieldNames().get(sheetNum); int rowNum = 3;
for (Object obj : objs) {
HSSFRow contentRow = sheets[sheetNum].createRow(rowNum);
contentRow.setHeight((short) 300);
HSSFCell[] cells = getCells(contentRow, setInfo.getFieldNames()
.get(sheetNum).length);
int cellNum = 1; // 去掉一列序号,因此从1开始
if (fieldNames != null) {
for (int num = 0; num < fieldNames.length; num++) { Object value = ReflectionUtil.invokeGetterMethod(obj,
fieldNames[num]);
cells[cellNum].setCellValue(value == null ? "" : value
.toString());
cellNum++;
}
}
rowNum++;
}
adjustColumnSize(sheets, sheetNum, fieldNames); // 自动调整列宽
sheetNum++;
}
wb.write(outputStream);
return outputStream;
} /**
* @Description: 初始化
*/
private static void init() {
wb = new HSSFWorkbook(); titleFont = wb.createFont();
titleStyle = wb.createCellStyle();
dateStyle = wb.createCellStyle();
dateFont = wb.createFont();
headStyle = wb.createCellStyle();
headFont = wb.createFont();
contentStyle = wb.createCellStyle();
contentFont = wb.createFont(); initTitleCellStyle();
initTitleFont();
initDateCellStyle();
initDateFont();
initHeadCellStyle();
initHeadFont();
initContentCellStyle();
initContentFont();
} /**
* @Description: 自动调整列宽
*/
private static void adjustColumnSize(HSSFSheet[] sheets, int sheetNum,
String[] fieldNames) {
for (int i = 0; i < fieldNames.length + 1; i++) {
sheets[sheetNum].autoSizeColumn(i, true);
}
} /**
* @Description: 创建标题行(需合并单元格)
*/
private static void createTableTitleRow(ExcelExportData setInfo,
HSSFSheet[] sheets, int sheetNum) {
CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, setInfo
.getFieldNames().get(sheetNum).length);
sheets[sheetNum].addMergedRegion(titleRange);
HSSFRow titleRow = sheets[sheetNum].createRow(0);
titleRow.setHeight((short) 800);
HSSFCell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(titleStyle);
titleCell.setCellValue(setInfo.getTitles()[sheetNum]);
} /**
* @Description: 创建日期行(需合并单元格)
*/
private static void createTableDateRow(ExcelExportData setInfo,
HSSFSheet[] sheets, int sheetNum) {
CellRangeAddress dateRange = new CellRangeAddress(1, 1, 0, setInfo
.getFieldNames().get(sheetNum).length);
sheets[sheetNum].addMergedRegion(dateRange);
HSSFRow dateRow = sheets[sheetNum].createRow(1);
dateRow.setHeight((short) 350);
HSSFCell dateCell = dateRow.createCell(0);
dateCell.setCellStyle(dateStyle);
// dateCell.setCellValue("导出时间:" + new
// SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
// .format(new Date()));
dateCell.setCellValue(new SimpleDateFormat("yyyy-MM-dd")
.format(new Date()));
} /**
* @Description: 创建表头行(需合并单元格)
*/
private static void creatTableHeadRow(ExcelExportData setInfo,
HSSFSheet[] sheets, int sheetNum) {
// 表头
HSSFRow headRow = sheets[sheetNum].createRow(2);
headRow.setHeight((short) 350);
// 序号列
HSSFCell snCell = headRow.createCell(0);
snCell.setCellStyle(headStyle);
snCell.setCellValue("序号");
// 列头名称
for (int num = 1, len = setInfo.getColumnNames().get(sheetNum).length; num <= len; num++) {
HSSFCell headCell = headRow.createCell(num);
headCell.setCellStyle(headStyle);
headCell.setCellValue(setInfo.getColumnNames().get(sheetNum)[num - 1]);
}
} /**
* @Description: 创建所有的Sheet
*/
private static HSSFSheet[] getSheets(int num, String[] names) {
HSSFSheet[] sheets = new HSSFSheet[num];
for (int i = 0; i < num; i++) {
sheets[i] = wb.createSheet(names[i]);
}
return sheets;
} /**
* @Description: 创建内容行的每一列(附加一列序号)
*/
private static HSSFCell[] getCells(HSSFRow contentRow, int num) {
HSSFCell[] cells = new HSSFCell[num + 1]; for (int i = 0, len = cells.length; i < len; i++) {
cells[i] = contentRow.createCell(i);
cells[i].setCellStyle(contentStyle);
} // 设置序号列值,因为出去标题行和日期行,所有-2
cells[0].setCellValue(contentRow.getRowNum() - 2); return cells;
} /**
* @Description: 初始化标题行样式
*/
private static void initTitleCellStyle() {
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
titleStyle.setFont(titleFont);
titleStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
} /**
* @Description: 初始化日期行样式
*/
private static void initDateCellStyle() {
dateStyle.setAlignment(CellStyle.ALIGN_CENTER_SELECTION);
dateStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
dateStyle.setFont(dateFont);
dateStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
} /**
* @Description: 初始化表头行样式
*/
private static void initHeadCellStyle() {
headStyle.setAlignment(CellStyle.ALIGN_CENTER);
headStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
headStyle.setFont(headFont);
headStyle.setFillBackgroundColor(IndexedColors.YELLOW.index);
headStyle.setBorderTop(CellStyle.BORDER_MEDIUM);
headStyle.setBorderBottom(CellStyle.BORDER_THIN);
headStyle.setBorderLeft(CellStyle.BORDER_THIN);
headStyle.setBorderRight(CellStyle.BORDER_THIN);
headStyle.setTopBorderColor(IndexedColors.BLUE.index);
headStyle.setBottomBorderColor(IndexedColors.BLUE.index);
headStyle.setLeftBorderColor(IndexedColors.BLUE.index);
headStyle.setRightBorderColor(IndexedColors.BLUE.index);
} /**
* @Description: 初始化内容行样式
*/
private static void initContentCellStyle() {
contentStyle.setAlignment(CellStyle.ALIGN_CENTER);
contentStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
contentStyle.setFont(contentFont);
contentStyle.setBorderTop(CellStyle.BORDER_THIN);
contentStyle.setBorderBottom(CellStyle.BORDER_THIN);
contentStyle.setBorderLeft(CellStyle.BORDER_THIN);
contentStyle.setBorderRight(CellStyle.BORDER_THIN);
contentStyle.setTopBorderColor(IndexedColors.BLUE.index);
contentStyle.setBottomBorderColor(IndexedColors.BLUE.index);
contentStyle.setLeftBorderColor(IndexedColors.BLUE.index);
contentStyle.setRightBorderColor(IndexedColors.BLUE.index);
contentStyle.setWrapText(true); // 字段换行
} /**
* @Description: 初始化标题行字体
*/
private static void initTitleFont() {
titleFont.setFontName("华文楷体");
titleFont.setFontHeightInPoints((short) 20);
titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
titleFont.setCharSet(Font.DEFAULT_CHARSET);
titleFont.setColor(IndexedColors.BLUE_GREY.index);
} /**
* @Description: 初始化日期行字体
*/
private static void initDateFont() {
dateFont.setFontName("隶书");
dateFont.setFontHeightInPoints((short) 10);
dateFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
dateFont.setCharSet(Font.DEFAULT_CHARSET);
dateFont.setColor(IndexedColors.BLUE_GREY.index);
} /**
* @Description: 初始化表头行字体
*/
private static void initHeadFont() {
headFont.setFontName("宋体");
headFont.setFontHeightInPoints((short) 10);
headFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
headFont.setCharSet(Font.DEFAULT_CHARSET);
headFont.setColor(IndexedColors.BLUE_GREY.index);
} /**
* @Description: 初始化内容行字体
*/
private static void initContentFont() {
contentFont.setFontName("宋体");
contentFont.setFontHeightInPoints((short) 10);
contentFont.setBoldweight(Font.BOLDWEIGHT_NORMAL);
contentFont.setCharSet(Font.DEFAULT_CHARSET);
contentFont.setColor(IndexedColors.BLUE_GREY.index);
} /**
* Excel导出数据类
*
* @author jimmy
*
*/
public static class ExcelExportData { /**
* 导出数据 key:String 表示每个Sheet的名称 value:List<?> 表示每个Sheet里的所有数据行
*/
private LinkedHashMap<String, List<?>> dataMap; /**
* 每个Sheet里的顶部大标题
*/
private String[] titles; /**
* 单个sheet里的数据列标题
*/
private List<String[]> columnNames; /**
* 单个sheet里每行数据的列对应的对象属性名称
*/
private List<String[]> fieldNames; public List<String[]> getFieldNames() {
return fieldNames;
} public void setFieldNames(List<String[]> fieldNames) {
this.fieldNames = fieldNames;
} public String[] getTitles() {
return titles;
} public void setTitles(String[] titles) {
this.titles = titles;
} public List<String[]> getColumnNames() {
return columnNames;
} public void setColumnNames(List<String[]> columnNames) {
this.columnNames = columnNames;
} public LinkedHashMap<String, List<?>> getDataMap() {
return dataMap;
} public void setDataMap(LinkedHashMap<String, List<?>> dataMap) {
this.dataMap = dataMap;
} }
}

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

 package com.cnblogs.yjmyzz.utils;

 import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List; import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert; /**
* 反射工具类.
*
* 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数.
*
*/ public class ReflectionUtil { private static Log logger = LogFactory.getLog(ReflectionUtil.class); static {
DateLocaleConverter dc = new DateLocaleConverter();
// dc.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" });
ConvertUtils.register(dc, Date.class);
} /**
* 调用Getter方法.
*/
public static Object invokeGetterMethod(Object target, String propertyName) {
String getterMethodName = "get" + StringUtils.capitalize(propertyName);
return invokeMethod(target, getterMethodName, new Class[] {},
new Object[] {});
} /**
* 调用Setter方法.使用value的Class来查找Setter方法.
*/
public static void invokeSetterMethod(Object target, String propertyName,
Object value) {
invokeSetterMethod(target, propertyName, value, null);
} /**
* 调用Setter方法.
*
* @param propertyType
* 用于查找Setter方法,为空时使用value的Class替代.
*/
public static void invokeSetterMethod(Object target, String propertyName,
Object value, Class<?> propertyType) {
Class<?> type = propertyType != null ? propertyType : value.getClass();
String setterMethodName = "set" + StringUtils.capitalize(propertyName);
invokeMethod(target, setterMethodName, new Class[] { type },
new Object[] { value });
} /**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
public static Object getFieldValue(final Object object,
final String fieldName) {
Field field = getDeclaredField(object, fieldName); if (field == null) {
throw new IllegalArgumentException("Could not find field ["
+ fieldName + "] on target [" + object + "]");
} makeAccessible(field); Object result = null;
try {
result = field.get(object);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常{}" + e.getMessage());
}
return result;
} /**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public static void setFieldValue(final Object object,
final String fieldName, final Object value) {
Field field = getDeclaredField(object, fieldName); if (field == null) {
throw new IllegalArgumentException("Could not find field ["
+ fieldName + "] on target [" + object + "]");
} makeAccessible(field); try {
field.set(object, value);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常:{}" + e.getMessage());
}
} /**
* 直接调用对象方法, 无视private/protected修饰符.
*/
public static Object invokeMethod(final Object object,
final String methodName, final Class<?>[] parameterTypes,
final Object[] parameters) {
Method method = getDeclaredMethod(object, methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Could not find method ["
+ methodName + "] parameterType " + parameterTypes
+ " on target [" + object + "]");
} method.setAccessible(true); try {
return method.invoke(object, parameters);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
} /**
* 循环向上转型, 获取对象的DeclaredField.
*
* 如向上转型到Object仍无法找到, 返回null.
*/
protected static Field getDeclaredField(final Object object,
final String fieldName) {
Assert.notNull(object, "object不能为空");
Assert.hasText(fieldName, "fieldName");
for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
.getSuperclass()) {
try {
return superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {// NOSONAR
// Field不在当前类定义,继续向上转型
}
}
return null;
} /**
* 强行设置Field可访问.
*/
protected static void makeAccessible(final Field field) {
if (!Modifier.isPublic(field.getModifiers())
|| !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
field.setAccessible(true);
}
} /**
* 循环向上转型, 获取对象的DeclaredMethod.
*
* 如向上转型到Object仍无法找到, 返回null.
*/
protected static Method getDeclaredMethod(Object object, String methodName,
Class<?>[] parameterTypes) {
Assert.notNull(object, "object不能为空"); for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
.getSuperclass()) {
try {
return superClass.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {// NOSONAR
// Method不在当前类定义,继续向上转型
}
}
return null;
} /**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class. eg. public UserDao
* extends HibernateDao<User>
*
* @param clazz
* The class to introspect
* @return the first generic declaration, or Object.class if cannot be
* determined
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> getSuperClassGenricType(final Class<?> clazz) {
return getSuperClassGenricType(clazz, 0);
} /**
* 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
*
* 如public UserDao extends HibernateDao<User,Long>
*
* @param clazz
* clazz The class to introspect
* @param index
* the Index of the generic ddeclaration,start from 0.
* @return the index generic declaration, or Object.class if cannot be
* determined
*/
@SuppressWarnings("unchecked")
public static Class getSuperClassGenricType(final Class<?> clazz,
final int index) {
Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName()
+ "'s superclass not ParameterizedType");
return Object.class;
} Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) {
logger.warn("Index: " + index + ", Size of "
+ clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName()
+ " not set the actual class on superclass generic parameter");
return Object.class;
} return (Class) params[index];
} /**
* 提取集合中的对象的属性(通过getter函数), 组合成List.
*
* @param collection
* 来源集合.
* @param propertyName
* 要提取的属性名.
*/ public static List convertElementPropertyToList(
final Collection collection, final String propertyName) {
List list = new ArrayList(); try {
for (Object obj : collection) {
list.add(PropertyUtils.getProperty(obj, propertyName));
}
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
} return list;
} /**
* 提取集合中的对象的属性(通过getter函数), 组合成由分割符分隔的字符串.
*
* @param collection
* 来源集合.
* @param propertyName
* 要提取的属性名.
* @param separator
* 分隔符.
*/
@SuppressWarnings("unchecked")
public static String convertElementPropertyToString(
final Collection collection, final String propertyName,
final String separator) {
List list = convertElementPropertyToList(collection, propertyName);
return StringUtils.join(list, separator);
} /**
* 转换字符串到相应类型.
*
* @param value
* 待转换的字符串
* @param toType
* 转换目标类型
*/
@SuppressWarnings("unchecked")
public static <T> T convertStringToObject(String value, Class<T> toType) {
try {
return (T) ConvertUtils.convert(value, toType);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
} /**
* 将反射时的checked exception转换为unchecked exception.
*/
public static RuntimeException convertReflectionExceptionToUnchecked(
Exception e) {
return convertReflectionExceptionToUnchecked(null, e);
} public static RuntimeException convertReflectionExceptionToUnchecked(
String desc, Exception e) {
desc = (desc == null) ? "Unexpected Checked Exception." : desc;
if (e instanceof IllegalAccessException
|| e instanceof IllegalArgumentException
|| e instanceof NoSuchMethodException) {
return new IllegalArgumentException(desc, e);
} else if (e instanceof InvocationTargetException) {
return new RuntimeException(desc,
((InvocationTargetException) e).getTargetException());
} else if (e instanceof RuntimeException) {
return (RuntimeException) e;
}
return new RuntimeException(desc, e);
} public static final <T> T getNewInstance(Class<T> cls) {
try {
return cls.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
} /**
* 拷贝 source 指定的porperties 属性 到 dest中
*
* @return void
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public static void copyPorperties(Object dest, Object source,
String[] porperties) throws InvocationTargetException,
IllegalAccessException {
for (String por : porperties) {
Object srcObj = invokeGetterMethod(source, por);
logger.debug("属性名:" + por + "------------- 属性值:" + srcObj);
if (srcObj != null) {
try {
BeanUtils.setProperty(dest, por, srcObj);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
throw e;
}
}
}
} /**
* 两者属性名一致时,拷贝source里的属性到dest里
*
* @return void
* @throws IllegalAccessException
* @throws InvocationTargetException
*/ public static void copyPorperties(Object dest, Object source)
throws IllegalAccessException, InvocationTargetException {
Class<? extends Object> srcCla = source.getClass();
Field[] fsF = srcCla.getDeclaredFields(); for (Field s : fsF) {
String name = s.getName();
Object srcObj = invokeGetterMethod(source, name);
try {
BeanUtils.setProperty(dest, name, srcObj);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
throw e;
}
}
// BeanUtils.copyProperties(dest, orig);
} public static void main(String[] args) throws InvocationTargetException,
IllegalAccessException {
/*
* Document document = new Document(); document.setId(2);
* document.setCreateDate(new Date()); DocumentVo dcoVo = new
* DocumentVo(); ReflectionUtils.copyPorperties(dcoVo, document,new
* String[]{"id","businessName","createDate","applyName","docTitle",
* "transactStatus"}); System.out.println(dcoVo.getId());
*/
}
}

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

 package com.cnblogs.yjmyzz.utils;

 import java.io.*;
import java.util.*;
import java.util.concurrent.*; /**
* 文件处理辅助类
*
* @author yjmyzz@126.com
* @version 0.2
* @since 2014-11-17
*
*/
public class FileUtil { /**
* 当前目录路径
*/
public static String currentWorkDir = System.getProperty("user.dir") + "\\"; /**
* 左填充
*
* @param str
* @param length
* @param ch
* @return
*/
public static String leftPad(String str, int length, char ch) {
if (str.length() >= length) {
return str;
}
char[] chs = new char[length];
Arrays.fill(chs, ch);
char[] src = str.toCharArray();
System.arraycopy(src, 0, chs, length - src.length, src.length);
return new String(chs); } /**
* 删除文件
*
* @param fileName
* 待删除的完整文件名
* @return
*/
public static boolean delete(String fileName) {
boolean result = false;
File f = new File(fileName);
if (f.exists()) {
result = f.delete(); } else {
result = true;
}
return result;
} /***
* 递归获取指定目录下的所有的文件(不包括文件夹)
*
* @param obj
* @return
*/
public static ArrayList<File> getAllFiles(String dirPath) {
File dir = new File(dirPath); ArrayList<File> files = new ArrayList<File>(); if (dir.isDirectory()) {
File[] fileArr = dir.listFiles();
for (int i = 0; i < fileArr.length; i++) {
File f = fileArr[i];
if (f.isFile()) {
files.add(f);
} else {
files.addAll(getAllFiles(f.getPath()));
}
}
}
return files;
} /**
* 获取指定目录下的所有文件(不包括子文件夹)
*
* @param dirPath
* @return
*/
public static ArrayList<File> getDirFiles(String dirPath) {
File path = new File(dirPath);
File[] fileArr = path.listFiles();
ArrayList<File> files = new ArrayList<File>(); for (File f : fileArr) {
if (f.isFile()) {
files.add(f);
}
}
return files;
} /**
* 获取指定目录下特定文件后缀名的文件列表(不包括子文件夹)
*
* @param dirPath
* 目录路径
* @param suffix
* 文件后缀
* @return
*/
public static ArrayList<File> getDirFiles(String dirPath,
final String suffix) {
File path = new File(dirPath);
File[] fileArr = path.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowerName = name.toLowerCase();
String lowerSuffix = suffix.toLowerCase();
if (lowerName.endsWith(lowerSuffix)) {
return true;
}
return false;
} });
ArrayList<File> files = new ArrayList<File>(); for (File f : fileArr) {
if (f.isFile()) {
files.add(f);
}
}
return files;
} /**
* 读取文件内容
*
* @param fileName
* 待读取的完整文件名
* @return 文件内容
* @throws IOException
*/
public static String read(String fileName) throws IOException {
File f = new File(fileName);
FileInputStream fs = new FileInputStream(f);
String result = null;
byte[] b = new byte[fs.available()];
fs.read(b);
fs.close();
result = new String(b);
return result;
} /**
* 写文件
*
* @param fileName
* 目标文件名
* @param fileContent
* 写入的内容
* @return
* @throws IOException
*/
public static boolean write(String fileName, String fileContent)
throws IOException {
return write(fileName, fileContent, true, true);
} /**
* 写文件
*
* @param fileName
* 完整文件名(类似:/usr/a/b/c/d.txt)
* @param fileContent
* 文件内容
* @param autoCreateDir
* 目录不存在时,是否自动创建(多级)目录
* @param autoOverWrite
* 目标文件存在时,是否自动覆盖
* @return
* @throws IOException
*/
public static boolean write(String fileName, String fileContent,
boolean autoCreateDir, boolean autoOverwrite) throws IOException {
return write(fileName, fileContent.getBytes(), autoCreateDir,
autoOverwrite);
} /**
* 写文件
*
* @param fileName
* 完整文件名(类似:/usr/a/b/c/d.txt)
* @param contentBytes
* 文件内容的字节数组
* @param autoCreateDir
* 目录不存在时,是否自动创建(多级)目录
* @param autoOverWrite
* 目标文件存在时,是否自动覆盖
* @return
* @throws IOException
*/
public static boolean write(String fileName, byte[] contentBytes,
boolean autoCreateDir, boolean autoOverwrite) throws IOException {
boolean result = false;
if (autoCreateDir) {
createDirs(fileName);
}
if (autoOverwrite) {
delete(fileName);
}
File f = new File(fileName);
FileOutputStream fs = new FileOutputStream(f);
fs.write(contentBytes);
fs.flush();
fs.close();
result = true;
return result;
} /**
* 追加内容到指定文件
*
* @param fileName
* @param fileContent
* @return
* @throws IOException
*/
public static boolean append(String fileName, String fileContent)
throws IOException {
boolean result = false;
File f = new File(fileName);
if (f.exists()) {
RandomAccessFile rFile = new RandomAccessFile(f, "rw");
byte[] b = fileContent.getBytes();
long originLen = f.length();
rFile.setLength(originLen + b.length);
rFile.seek(originLen);
rFile.write(b);
rFile.close();
}
result = true;
return result;
} /**
* 拆分文件
*
* @param fileName
* 待拆分的完整文件名
* @param byteSize
* 按多少字节大小拆分
* @return 拆分后的文件名列表
* @throws IOException
*/
public List<String> splitBySize(String fileName, int byteSize)
throws IOException {
List<String> parts = new ArrayList<String>();
File file = new File(fileName);
int count = (int) Math.ceil(file.length() / (double) byteSize);
int countLen = (count + "").length();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(count,
count * 3, 1, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(count * 2)); for (int i = 0; i < count; i++) {
String partFileName = file.getPath() + "."
+ leftPad((i + 1) + "", countLen, '0') + ".part";
threadPool.execute(new SplitRunnable(byteSize, i * byteSize,
partFileName, file));
parts.add(partFileName);
}
return parts;
} /**
* 合并文件
*
* @param dirPath
* 拆分文件所在目录名
* @param partFileSuffix
* 拆分文件后缀名
* @param partFileSize
* 拆分文件的字节数大小
* @param mergeFileName
* 合并后的文件名
* @throws IOException
*/
public void mergePartFiles(String dirPath, String partFileSuffix,
int partFileSize, String mergeFileName) throws IOException {
ArrayList<File> partFiles = FileUtil.getDirFiles(dirPath,
partFileSuffix);
Collections.sort(partFiles, new FileComparator()); RandomAccessFile randomAccessFile = new RandomAccessFile(mergeFileName,
"rw");
randomAccessFile.setLength(partFileSize * (partFiles.size() - 1)
+ partFiles.get(partFiles.size() - 1).length());
randomAccessFile.close(); ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
partFiles.size(), partFiles.size() * 3, 1, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(partFiles.size() * 2)); for (int i = 0; i < partFiles.size(); i++) {
threadPool.execute(new MergeRunnable(i * partFileSize,
mergeFileName, partFiles.get(i)));
} } /**
* 根据文件名,比较文件
*
* @author yjmyzz@126.com
*
*/
private class FileComparator implements Comparator<File> {
public int compare(File o1, File o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
} /**
* 创建(多级)目录
*
* @param filePath
* 完整的文件名(类似:/usr/a/b/c/d.xml)
*/
public static void createDirs(String filePath) {
File file = new File(filePath);
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
} } /**
* 分割处理Runnable
*
* @author yjmyzz@126.com
*
*/
private class SplitRunnable implements Runnable {
int byteSize;
String partFileName;
File originFile;
int startPos; public SplitRunnable(int byteSize, int startPos, String partFileName,
File originFile) {
this.startPos = startPos;
this.byteSize = byteSize;
this.partFileName = partFileName;
this.originFile = originFile;
} public void run() {
RandomAccessFile rFile;
OutputStream os;
try {
rFile = new RandomAccessFile(originFile, "r");
byte[] b = new byte[byteSize];
rFile.seek(startPos);// 移动指针到每“段”开头
int s = rFile.read(b);
os = new FileOutputStream(partFileName);
os.write(b, 0, s);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 合并处理Runnable
*
* @author yjmyzz@126.com
*
*/
private class MergeRunnable implements Runnable {
long startPos;
String mergeFileName;
File partFile; public MergeRunnable(long startPos, String mergeFileName, File partFile) {
this.startPos = startPos;
this.mergeFileName = mergeFileName;
this.partFile = partFile;
} public void run() {
RandomAccessFile rFile;
try {
rFile = new RandomAccessFile(mergeFileName, "rw");
rFile.seek(startPos);
FileInputStream fs = new FileInputStream(partFile);
byte[] b = new byte[fs.available()];
fs.read(b);
fs.close();
rFile.write(b);
rFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

最后是调用示例:

     @Test
public void testExcel() throws Exception { List<String[]> columNames = new ArrayList<String[]>();
columNames.add(new String[] { "运单号", "代理人" });
columNames.add(new String[] { "运单号", "代理人" }); List<String[]> fieldNames = new ArrayList<String[]>();
fieldNames.add(new String[] { "awbNumber", "agent" });
fieldNames.add(new String[] { "awbNumber", "agent" }); LinkedHashMap<String, List<?>> map = new LinkedHashMap<String, List<?>>();
map.put("运单月报(1月)", getData1());
map.put("运单月报(2月)", getData2()); ExcelExportData setInfo = new ExcelExportData();
setInfo.setDataMap(map);
setInfo.setFieldNames(fieldNames);
setInfo.setTitles(new String[] { "航空运单报表1","航空运单报表2"});
setInfo.setColumnNames(columNames); // 将需要导出的数据输出到文件
System.out.println(ExcelUtil.export2File(setInfo, "r:/test.xls")); }

导出后的样子如下:

java:POI导出excel的更多相关文章

  1. 重构:以Java POI 导出EXCEL为例

    重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...

  2. Java POI 导出EXCEL经典实现 Java导出Excel

    转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...

  3. 重构:以Java POI 导出EXCEL为例2

    前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...

  4. Java POI 导出excel表

    1.首先下载poi-3.6-20091214.jar,下载地址如下: http://download.csdn.net/detail/evangel_z/3895051 2.Student.java ...

  5. java POI导出Excel文件数据库的数据

    在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作.这里我简单实现导出Excel文件. POI jar ...

  6. Java POI导出Excel不弹框选择下载路径(下载文件不选择下载路径,默认) Chrome

    在Chrome浏览器中,Java导出Excel文件时,浏览器弹出提示框,需要选择下载路径 在Chrome中的高级设置中,把“下载前询问每个文件的保存位置”去掉就解决了 DEEPLOVE(LC)

  7. JAVA POI导出EXCEL 动态表头、多级表头、动态数据

    导出Excel文件是业务中经常遇到的需求,以下是经常遇到的一些问题: 1,导出中文文件名乱码 String filename = "sheet1";response.setChar ...

  8. java poi导出EXCEL xls文件代码

    String _currentPage = request.getParameter("currentPage"); Integer currentPage = 0; if(_cu ...

  9. Java POI 导出EXCEL经典实现

    import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; i ...

随机推荐

  1. LinkedHashMap及其源码分析

    以下内容基于jdk1.7.0_79源码: 什么是LinkedHashMap 继承自HashMap,一个有序的Map接口实现,这里的有序指的是元素可以按插入顺序或访问顺序排列: LinkedHashMa ...

  2. MongoDB 安装(Window/Linux)

    MongoDB安装在Windows上 在 Windows上,首先要安装 MongoDB下载最新发布的MongoDB: http://www.mongodb.org/downloads 确保得到正确的版 ...

  3. df,du,mount

    df 查看当前系统中文件系统的使用情况 $df [-aTh]缺省选项查看当前系统的所有文件系统 -a列出所有的信息 -T列出文件系统类型 -hhuman-readable,用合适的单位表示大小 $df ...

  4. php反射机制

    PHP5添加了一项新的功能:Reflection.这个功能使得phper可以reverse-engineer class, interface,function,method and extensio ...

  5. JAVA 基本运算符(摘)

    (搞自:Java经典入门教程) http://wenku.baidu.com/link?url=IoWI58cD5vzeHN-NL4pN7Gren-RfzydrhjDlETAByC9L-9ANinyL ...

  6. FastCV安装报错---LaunchAnyWhere错误:载入Java VM时Windows出现错误:2

  7. 解决Qt在openSUSE上编译出现“cannot find -lGL”错误

    在openSUSE上编译QT5.4程序出现“cannot find -lGL”,就连example都无法通过编译.QT是在官网下的最新的安装包. 大体意思是,缺少qt运行时所需要的openGL库.决绝 ...

  8. 退役了退役了-AJAX

    hi 昨晚打球悲剧的把脚崴了. 要知道,上一次崴脚是四年前:那一次伤的是左脚,也是我这么多年打篮球的生涯中,这么多次崴脚中,最严重的一次受伤.休息了整整一个月,受寝室兄弟们的无微不至的照顾,最后也买了 ...

  9. 使用ajaxfileupload.js上传文件

    一直以来上传文件都是使用form表单上传文件,也看到过有人使用js上传文件,不过看起来蛮简单的也就没有怎么去理会.今天突然要使用这种方式上传文件,期间还遇到点问题.因此就记录下来,方便以后遇到这样的问 ...

  10. 2016中国大学生程序设计竞赛(长春) Ugly Problem 模拟+大数减法

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5920 我们的思路是: 对于一个串s,先根据s串前一半复制到后一半构成一个回文串, 如果这个回文串比s小, ...