java导出Excel

Jakarta POI 是一套用于访问微软格式文档的Java API。Jakarta POI有很多组件组成,其中有用于操作Excel格式文件的XSSF和用于操作Word的HWPF,在各种组件中目前只有用于操作Excel的XSSF相对成熟。

XSSF只对xls后缀文件格式操作,XSSF可以对xlsx后缀文件格式操作。其他方法只需把H替换成X就可以转换使用。

官方主页http://poi.apache.org/index.html

API文档http://poi.apache.org/apidocs/index.html

引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 对xls后缀的表格操作 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.1.5</version>
</dependency>
<!-- 对xlsx后缀的表格操作 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
基本组件
  1. XSSFWorkbook:Excel对象,相当于一个 .xls/.xlsx 文件
  2. XSSFSheet:工作表对象,Excel文件包涵的sheet,一个对象代表一个表单
  3. XSSFRow:表示表格中的行对象。
  4. XSSFCell:表示表格中的单元格对象。
  5. XSSFHeader:Excel文档Sheet的页眉。
  6. XSSFFooter:Excel文档Sheet的页脚。
  7. XSSFDataFormat:日期格式。
  8. XSSFFont:字体对象。
  9. XSSFCellStyle:单元格样式(对齐样式、边框等)
  10. XSSFComment:批注(注释)。
  11. XSSFPatriarch:和XSSFComment用于创建注释的位置。
  12. XSSFColor:颜色对象。
  13. XSSFDateUtil:日期辅助工具
  14. XSSFPrintSetup:打印辅助工具
  15. XSSFErrorConstants:错误信息表
基本操作
创建Excel对象
1
2
//创建Excel对象
XSSFWorkbook workbook = new XSSFWorkbook();
使用workbook 对象创建工作表对象
1
2
//创建工作表单
XSSFSheet sheet = workbook.createSheet("对象报表");
创建行和操作单元格对象
1
2
3
4
5
6
//创建XSSFRow对象 (行)
XSSFRow row = sheet.createRow(0);
//创建XSSFCell对象 (单元格)
XSSFCell cell=row.createCell(0);
//设置单元格的值
cell.setCellValue("单元格中的中文");
保存Excel文件
1
2
3
4
//输出Excel文件  
FileOutputStream output=new FileOutputStream("d:\\workbook.xls");
workbook.write(output);
output.flush();
示例
ExcelUtil工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.yundao.util;

import java.util.List;
import java.util.Map;

import org.apache.poi.XSSF.usermodel.XSSFCell;
import org.apache.poi.XSSF.usermodel.XSSFCellStyle;
import org.apache.poi.XSSF.usermodel.XSSFRow;
import org.apache.poi.XSSF.usermodel.XSSFSheet;
import org.apache.poi.XSSF.usermodel.XSSFWorkbook;

/**
* excel表格操作工具类
*
*/
public class ExcelUtil {

/**
* 导出Excel
* @param sheetName sheet名称
* @param title 标题
* @param exportDataList 内容
* @param wb XSSFWorkbook对象
* @return
*/
public static XSSFWorkbook getXSSFWorkbook(
String sheetName, String []title, List<Map<String, Object>> exportDataList, XSSFWorkbook wb){

// 第一步,创建一个XSSFWorkbook,对应一个Excel文件
if(wb == null){
wb = new XSSFWorkbook();
}

// 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
XSSFSheet sheet = wb.createSheet(sheetName);

// 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
XSSFRow row = sheet.createRow(0);

// 第四步,创建单元格,并设置值表头 设置表头居中
XSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式

//声明列对象
XSSFCell cell = null;

//创建标题
for(int i=0;i<title.length;i++){
cell = row.createCell(i);
cell.setCellValue(title[i]);
cell.setCellStyle(style);
}

//创建内容
for(int i=0;i<exportDataList.size();i++){
row = sheet.createRow(i + 1);
for(int j=0;j<exportDataList.get(i).size();j++){
//将内容按顺序赋给对应的列对象
row.createCell(j).setCellValue(exportDataList.get(i).get(j+"")+"");
}
}
return wb;
}
}
主代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.XSSF.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


/**
* 导出数据到excel
* @return
*/
@RequestMapping("exportExcel")
@ResponseBody
public Map<String,Object> exportExcel(HttpServletRequest request,HttpServletResponse response) {
try {
//获取导出到excel 的数据
//sql查询的时候,要将查询出的每个字段起个别名 别名的格式必须是 从0开始依次递增
//例如 select id '0', userName '1', userPhone '2', userAddress '3' from user

List<Map<String, Object>> exportDataList = demoService.getExportData(request,response);

//设置excel标题 查询几个字段,就写几个标题,标题顺序跟0123对应
String[] title = {"编号","用户姓名","用户电话","用户地址"};

//excel文件名
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
String fileName = df.format(new Date())+".xls";

//sheet名
String sheetName = "自主设置";

//创建XSSFWorkbook
XSSFWorkbook wb = ExcelUtil.getXSSFWorkbook(sheetName, title, exportDataList, null);

//响应到客户端
try {
fileName = new String(fileName.getBytes(),"ISO8859-1");
//xlsx格式
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//xls格式
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");

OutputStream os = response.getOutputStream();
wb.write(os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
log.debug("exportExcel接口异常", e);

}
return null;
}
个性化导出——样式设置
合并单元格,设置宽、高
1
2
3
4
5
6
7
8
9
10
//合并单元格前3列
sheet.addMergedRegion(new CellRangeAddress(0,0,0,3));
//CellRangeAddress参数:起始行,截至行,起始列, 截至列

//设置缺省列高
sheet.setDefaultRowHeightInPoints(20);
//设置缺省列宽
sheet.setDefaultColumnWidth(30);
//自定义300 * 60
sheet.setColumnWidth(cell.getColumnIndex(), 300 * 60);
设置单元格样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 实例化样式对象
XSSFCellStyle cellStyle = workbook.createCellStyle();
// 两端对齐
cellStyle.setAlignment(XSSFCellStyle.ALIGN_JUSTIFY);
// 垂直居中
cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
// 填充图案---填充方式
cellStyle.setFillPattern(XSSFCellStyle.DIAMONDS);
// 设置前景色 (这个要写在背景色的前面)
cellStyle.setFillForegroundColor(XSSFColor.RED.index);
// 设置背景颜色
cellStyle.setFillBackgroundColor(XSSFColor.LIGHT_YELLOW.index);
// 设置边框
cellStyle.setBorderBottom(XSSFCellStyle.BORDER_SLANTED_DASH_DOT);
// 边框颜色
cellStyle.setBottomBorderColor(XSSFColor.DARK_RED.index);
// 日期展示格式
cellStyle.setDataFormat(XSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));

//将样式应用于单元格
cell.setCellStyle(cellStyle);
//将样式应用到行
row.setRowStyle(cellStyle);
设置字体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 实例化字体对象
XSSFFont fontStyle = workbook.createFont();
// 字体
fontStyle.setFontName("宋体");
// 高度
fontStyle.setFontHeightInPoints((short)12);
// 字体
font.setColor(XSSFColor.BLUE.index);
// 加粗
fontStyle.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 斜体
font.setItalic(true);
// 下划线
font.setUnderline(XSSFFont.U_SINGLE);
// 将字体应用于单元格样式中
cellStyle.setFont(font);
示例
导出Excel工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
public void exportExcel(String title, String[] headers, Collection<T> dataset, OutputStream out, String pattern,XSSFWorkbook workbook)  
{
// 声明一个工作薄 生成一个表格
XSSFSheet sheet = workbook.getSheet(title);
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth((short) 15);
// 生成一个样式
XSSFCellStyle style = workbook.createCellStyle();
// 设置这些样式
style.setFillForegroundColor(XSSFColor.SKY_BLUE.index);
style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 生成一个字体
XSSFFont font = workbook.createFont();
font.setColor(XSSFColor.VIOLET.index);
font.setFontHeightInPoints((short) 12);
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
// 生成并设置另一个样式
XSSFCellStyle style2 = workbook.createCellStyle();
style2.setFillForegroundColor(XSSFColor.LIGHT_YELLOW.index);
style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
// 生成另一个字体
XSSFFont font2 = workbook.createFont();
font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样式
style2.setFont(font2);
// 声明一个画图的顶级管理器
XSSFPatriarch patriarch = sheet.createDrawingPatriarch();
// 定义注释的大小和位置,详见文档
XSSFComment comment = patriarch.createComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
// 设置注释内容
comment.setString(new XSSFRichTextString("可以在POI中添加注释!"));
// 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
comment.setAuthor("leno");

// 产生表格标题行
XSSFRow row = sheet.createRow(0);
for (short i = 0; i < headers.length; i++)
{
XSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
XSSFRichTextString text = new XSSFRichTextString(headers[i]);
cell.setCellValue(text);
}
// 遍历集合数据,产生数据行
Iterator<T> it = dataset.iterator();
int index = 0;
while (it.hasNext())
{
index++;
row = sheet.createRow(index);
T t = (T) it.next();
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
Field[] fields = t.getClass().getDeclaredFields();
for (short i = 0; i < fields.length; i++)
{
XSSFCell cell = row.createCell(i);
cell.setCellStyle(style2);
Field field = fields[i];
String fieldName = field.getName();
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try
{
Class tCls = t.getClass();
Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
Object value = getMethod.invoke(t, new Object[] {});
// 判断值的类型后进行强制类型转换
String textValue = null;
if (value instanceof Boolean)
{
boolean bValue = (Boolean) value;
textValue = "男";
if (!bValue)
{
textValue = "女";
}
}
else if (value instanceof Date)
{
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
textValue = sdf.format(date);
}
else if (value instanceof byte[])
{
// 有图片时,设置行高为60px;
row.setHeightInPoints(60);
// 设置图片所在列宽度为80px,注意这里单位的一个换算
sheet.setColumnWidth(i, (short) (35.7 * 80));
// sheet.autoSizeColumn(i);
byte[] bsValue = (byte[]) value;
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0,1023, 255, (short) 6, index, (short) 6, index);
anchor.setAnchorType(2);
patriarch.createPicture(anchor, workbook.addPicture(bsValue, XSSFWorkbook.PICTURE_TYPE_JPEG));
}
else
{
// 其它数据类型都当作字符串简单处理
textValue = value == null? "": value.toString();
}
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
if (textValue != null)
{
Pattern p = Pattern.compile("^//d+(//.//d+)?$");
Matcher matcher = p.matcher(textValue);
if (matcher.matches())
{
// 是数字当作double处理
cell.setCellValue(Double.parseDouble(textValue));
}
else
{
XSSFRichTextString richString = new XSSFRichTextString(textValue);
XSSFFont font3 = workbook.createFont();
font3.setColor(XSSFColor.BLUE.index);
richString.applyFont(font3);
cell.setCellValue(richString);
}
}
}
catch (SecurityException e)
{
e.printStackTrace();
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
finally
{
// 清理资源
}
}
}
}
主代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//用于导出的数据集合
List<PBillBean> dataset = new ArrayList<PBillBean>();
//填充dataset
for (int i = 0; i < 10; i++) {
PBillBean bean = new PBillBean();
dataset.add(bean);
}
//临时文件
File tempFile = null;
try {
//Excel导出工具类
ExportExcel<PBillBean> ex = new ExportExcel<PBillBean>();
//导出的标题列
String[] headers = { "标题1", "标题2", "标题3", "标题4", "标题5", "标题6" };
//时间格式化
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
//要保存的文件名
String filename = "bill_" + format.format(new Date()) + ".xls";
//要保存的根目录
String rootDir = request.getSession().getServletContext().getRealPath("/");
//要保存的目录路径
String path = rootDir + File.separator + "tempfile";
File saveDir = new File(path);
if (!saveDir.exists()) {
saveDir.mkdirs();// 如果文件不存在则创建文件夹
}
//文件路径
path = path + File.separator + filename;
tempFile = new File(path); //初始化临时文件
//输出流
OutputStream out = new FileOutputStream(tempFile);
//实例化Excel表格
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表单
String[] sheetNames = { "对账报表" };
for (int i = 0; i < sheetNames.length; i++) {
workbook.createSheet(sheetNames[i]);
}
//导出到Excel
ex.exportExcel(sheetNames[0], headers, dataset, out,
"yyyy-MM-dd HH:mm", workbook);
try {
//保存文件
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
out.close();
// 以流的形式下载文件。
BufferedInputStream fis = new BufferedInputStream(
new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename="
+ new String(filename.getBytes()));
response.addHeader("Content-Length", "" + tempFile.length());
OutputStream toClient = new BufferedOutputStream(
response.getOutputStream());
response.setContentType("application/vnd.ms-excel;charset=utf-8");
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (tempFile != null && tempFile.exists()) {
tempFile.delete();// 删除临时文件
}
}
public static void testXSSF() throws Exception {
// 创建一个工作簿
XSSFWorkbook wb = new XSSFWorkbook();
// 创建一个工作表
XSSFSheet sheet = wb.createSheet();
// 创建字体
XSSFFont font1 = wb.createFont();
XSSFFont font2 = wb.createFont();
font1.setFontHeightInPoints((short) 14);
font1.setColor(XSSFColor.XSSFColorPredefined.RED.getIndex());
font2.setFontHeightInPoints((short) 12);
font2.setColor(XSSFColor.XSSFColorPredefined.BLUE.getIndex());
// 创建单元格样式
XSSFCellStyle css1 = wb.createCellStyle();
XSSFCellStyle css2 = wb.createCellStyle();
XSSFDataFormat df = wb.createDataFormat();
// 设置单元格字体及格式
css1.setFont(font1);
css1.setDataFormat(df.getFormat("#,##0.0"));
css2.setFont(font2);
css2.setDataFormat(XSSFDataFormat.getBuiltinFormat("text"));
// 创建行
for (int i = 0; i < 20; i++) {
XSSFRow row = sheet.createRow(i);
for (int j = 0; j < 10; j = j + 2) {
XSSFCell cell = row.createCell(j);
cell.setCellValue("Spring");
cell.setCellStyle(css1);

XSSFCell cell2 = row.createCell(j+1);
cell2.setCellValue(new XSSFRichTextString("Hello! " + j));
cell2.setCellStyle(css2);
}
}
// 写文件
FileOutputStream fos = new FileOutputStream("F:/wb.xls");
wb.write(fos);
fos.close();
}