1、 Excel导出的核心方法在ExportExcel类中,使用时请将该类完整的引入。
1 import java.io.IOException;
2 import java.io.OutputStream;
3 import java.lang.reflect.Field;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.text.SimpleDateFormat;
7 import java.util.Collection;
8 import java.util.Date;
9 import java.util.Iterator;
10 import java.util.regex.Matcher;
11 import java.util.regex.Pattern;
12
13 import org.apache.poi.hssf.usermodel.HSSFCell;
14 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
15 import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
16 import org.apache.poi.hssf.usermodel.HSSFComment;
17 import org.apache.poi.hssf.usermodel.HSSFFont;
18 import org.apache.poi.hssf.usermodel.HSSFPatriarch;
19 import org.apache.poi.hssf.usermodel.HSSFRichTextString;
20 import org.apache.poi.hssf.usermodel.HSSFRow;
21 import org.apache.poi.hssf.usermodel.HSSFSheet;
22 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
23 import org.apache.poi.hssf.util.CellRangeAddress;
24 import org.apache.poi.hssf.util.HSSFColor;
25 import org.apache.poi.hssf.util.Region;
26
27
28 /**
29 * 利用开源组件POI3.10动态导出EXCEL文档
30 *
31 * @author dqz
32 * @version v1.0
33 * @param <T>
34 * 应用泛型,代表任意一个符合javabean风格的类
35 * 注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
36 * byte[]表jpg格式的图片数据
37 */
38 public class ExportExcel<T> {
39 public void exportExcel(Collection<T> dataset, OutputStream out) {
40 exportExcel("测试POI导出EXCEL文档", null, dataset, out, "yyyy-MM-dd");
41 }
42
43 public void exportExcel(String[] headers, Collection<T> dataset,
44 OutputStream out) {
45 exportExcel("测试POI导出EXCEL文档", headers, dataset, out, "yyyy-MM-dd");
46 }
47
48 public void exportExcel(String[] headers, Collection<T> dataset,
49 OutputStream out, String pattern) {
50 exportExcel("测试POI导出EXCEL文档", headers, dataset, out, pattern);
51 }
52
53 /**
54 * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符合一定条件的数据以EXCEL 的形式输出到指定IO设备上
55 *
56 * @param title
57 * 表格标题名
58 * @param headers
59 * 表格属性列名数组
60 * @param dataset
61 * 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
62 * javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
63 * @param out
64 * 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
65 * @param pattern
66 * 如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
67 */
68 @SuppressWarnings("unchecked")
69 public void exportExcel(String title, String[] headers,
70 Collection<T> dataset, OutputStream out, String pattern) {
71 // 声明一个工作薄
72 HSSFWorkbook workbook = new HSSFWorkbook();
73 // 生成一个表格
74 HSSFSheet sheet = workbook.createSheet(title);
75 // 设置表格默认列宽度为15个字节
76 sheet.setDefaultColumnWidth((short) 15);
77 // 生成一个样式
78 HSSFCellStyle style = workbook.createCellStyle();
79 // 设置这些样式
80 style.setFillForegroundColor(HSSFColor.WHITE.index);
81 style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
82 style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
83 style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
84 style.setBorderRight(HSSFCellStyle.BORDER_THIN);
85 style.setBorderTop(HSSFCellStyle.BORDER_THIN);
86 style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
87 // 生成一个字体
88 HSSFFont font = workbook.createFont();
89 font.setColor(HSSFColor.BLACK.index);
90 font.setFontHeightInPoints((short) 12);
91 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
92 // 把字体应用到当前的样式
93 style.setFont(font);
94 // 生成并设置另一个样式
95 HSSFCellStyle style2 = workbook.createCellStyle();
96 style2.setFillForegroundColor(HSSFColor.WHITE.index);
97 style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
98 style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
99 style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
100 style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
101 style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
102 style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
103 style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
104 // 生成另一个字体
105 HSSFFont font2 = workbook.createFont();
106 font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
107 // 把字体应用到当前的样式
108 style2.setFont(font2);
109
110 // 声明一个画图的顶级管理器
111 HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
112 // 定义注释的大小和位置,详见文档
113 HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
114 0, 0, 0, (short) 4, 2, (short) 6, 5));
115 // 设置注释内容
116 comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
117 // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
118 comment.setAuthor("leno");
119
120 // 产生表格标题行
121 HSSFRow row = sheet.createRow(0);
122 for (short i = 0; i < headers.length; i++) {
123 HSSFCell cell = row.createCell(i);
124 cell.setCellStyle(style);
125 HSSFRichTextString text = new HSSFRichTextString(title);
126 cell.setCellValue(text);
127 }
128 sheet.addMergedRegion(new CellRangeAddress(0, 0, 0 , headers.length-1));
129 row = sheet.createRow(1);
130 for (short i = 0; i < headers.length; i++) {
131 HSSFCell cell = row.createCell(i);
132 cell.setCellStyle(style);
133 HSSFRichTextString text = new HSSFRichTextString(headers[i]);
134 cell.setCellValue(text);
135 }
136
137 // 遍历集合数据,产生数据行
138 Iterator<T> it = dataset.iterator();
139 int index = 1;
140 while (it.hasNext()) {
141 index++;
142 row = sheet.createRow(index);
143 T t = (T) it.next();
144 // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
145 Field[] fields = t.getClass().getDeclaredFields();
146 for (short i = 0; i < fields.length; i++) {
147 HSSFCell cell = row.createCell(i);
148 cell.setCellStyle(style2);
149 Field field = fields[i];
150 String fieldName = field.getName();
151 String getMethodName = "get"
152 + fieldName.substring(0, 1).toUpperCase()
153 + fieldName.substring(1);
154 try {
155 Class tCls = t.getClass();
156 Method getMethod = tCls.getMethod(getMethodName,
157 new Class[] {});
158 Object value = getMethod.invoke(t, new Object[] {});
159 // 判断值的类型后进行强制类型转换
160 String textValue = null;
161 // if (value instanceof Integer) {
162 // int intValue = (Integer) value;
163 // cell.setCellValue(intValue);
164 // } else if (value instanceof Float) {
165 // float fValue = (Float) value;
166 // textValue = new HSSFRichTextString(
167 // String.valueOf(fValue));
168 // cell.setCellValue(textValue);
169 // } else if (value instanceof Double) {
170 // double dValue = (Double) value;
171 // textValue = new HSSFRichTextString(
172 // String.valueOf(dValue));
173 // cell.setCellValue(textValue);
174 // } else if (value instanceof Long) {
175 // long longValue = (Long) value;
176 // cell.setCellValue(longValue);
177 // }
178 if (value instanceof Boolean) {
179 boolean bValue = (Boolean) value;
180 textValue = "男";
181 if (!bValue) {
182 textValue = "女";
183 }
184 } else if (value instanceof Date) {
185 Date date = (Date) value;
186 SimpleDateFormat sdf = new SimpleDateFormat(pattern);
187 textValue = sdf.format(date);
188 } else if (value instanceof byte[]) {
189 // 有图片时,设置行高为60px;
190 row.setHeightInPoints(60);
191 // 设置图片所在列宽度为80px,注意这里单位的一个换算
192 sheet.setColumnWidth(i, (short) (35.7 * 80));
193 // sheet.autoSizeColumn(i);
194 byte[] bsValue = (byte[]) value;
195 HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0,
196 1023, 255, (short) 6, index, (short) 6, index);
197 anchor.setAnchorType(2);
198 patriarch.createPicture(anchor, workbook.addPicture(
199 bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
200 } else {
201 // 其它数据类型都当作字符串简单处理
202 textValue = value.toString();
203 }
204 // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
205 if (textValue != null) {
206 Pattern p = Pattern.compile("^//d+(//.//d+)?$");
207 Matcher matcher = p.matcher(textValue);
208 if (matcher.matches()) {
209 // 是数字当作double处理
210 cell.setCellValue(Double.parseDouble(textValue));
211 } else {
212 HSSFRichTextString richString = new HSSFRichTextString(
213 textValue);
214 HSSFFont font3 = workbook.createFont();
215 font3.setColor(HSSFColor.BLACK.index);
216 richString.applyFont(font3);
217 cell.setCellValue(richString);
218 }
219 }
220 } catch (SecurityException e) {
221 e.printStackTrace();
222 } catch (NoSuchMethodException e) {
223 e.printStackTrace();
224 } catch (IllegalArgumentException e) {
225 e.printStackTrace();
226 } catch (IllegalAccessException e) {
227 e.printStackTrace();
228 } catch (InvocationTargetException e) {
229 e.printStackTrace();
230 } finally {
231 // 清理资源
232 }
233 }
234 }
235 try {
236 workbook.write(out);
237 } catch (IOException e) {
238 e.printStackTrace();
239 }
240 }
241
242 }
2、 创建ModelExcel数据模版类,该类用来记录所需导出到Excel的字段列,类中只包含字段属性及其get,set方法。
注:字段属性的先后顺序代表导出Excel中字段的先后顺序,get,set方法的先后顺序请与字段属性的先后顺序对应。
3、 构造导出方法,实现数据导出Excel。该方法中内容如下:
1 Public void ExportToExcel()
2 {
3 // 数据列表
4 List<ModelExcel> ds = new ArrayList<ModelExcel>();
5 /*
6 *向ds中插入导出数据
7 */
8 //创建ExportExcel对象
9 ExportExcel<ModelExcel> ex = new ExportExcel<ModelExcel>();
10 //构造导出Excel的头标题,与ModelExcel类的字段属性一一对应
11 String[] headers = { "列1", "列2", "列3", "列4"};
12 // 导出
13 try {
14 //获取xls文件存储路径
15 String filepath = “D:\textExcel.xls”;
16 OutputStream out = new FileOutputStream(filepath);
17 //导出Excel
18 ex.exportExcel("数据表单标题",headers, ds, out,"yyyy-MM-dd");
19 out.close();
20 } catch (FileNotFoundException e) {
21 e.printStackTrace();
22 } catch (IOException e) {
23 e.printStackTrace();
24 }
25 }
4、 应用举例
1)引入ExportExcel类
2)创建StudentExcel数据模版类
Public class StudentExcel
{
private int rowindex; //序号
private String name; //名称
private String sex; //性别public void setRowindex(int rowindex)
{
this.rowindex = rowindex;
}
public int getRowindex()
{
return rowindex;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setSex(String sex)
{
this.sex = sex;
}
public int getSex()
{
return sex;
}
}
3)构造导出方法
Public void ExportToExcel()
{
// 数据列表
List<StudentExcel> ds = new ArrayList<StudentExcel>();
//向ds中插入导出数据
StudentExcel s1 = new StudentExcel();
s1. setRowindex(1);
s1. setName(“张三”);
s1. setSex(“男”);
ds.add(s1);
StudentExcel s2 = new StudentExcel();
s2. setRowindex(2);
s2. setName(“李四”);
s2. setSex(“男”);
ds.add(s2);
StudentExcel s3 = new StudentExcel();
s3. setRowindex(3);
s3. setName(“王五”);
s3. setSex(“男”);
ds.add(s2);//创建ExportExcel对象
ExportExcel<StudentExcel> ex = new ExportExcel<SExcel>();
//构造导出Excel的头标题
String[] headers = { "序号", "名称", "性别"};
// 导出
try {
//获取xls文件存储路径
String filepath = “D:\studentExcel.xls”;
OutputStream out = new FileOutputStream(filepath);
//导出Excel
ex.exportExcel("学生清单",headers, ds, out,"yyyy-MM-dd");
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4)main函数调用运行
public static void main(String[] args) {
ExportToExcel();
}
5)导出结果