今天我们来讲一讲一个比较完整的java用poi导出Excel表格
1、第一步新建一个项目,项目结构如下:
2、第二步,在控制器创建一个主方法
public static void main(String[] args) {
//得到数据
List list=new ArrayList();
list.add(new Student(1,"张三","一班",91,101,81,100,96,80));
list.add(new Student(2,"李四","二班",95,108,67,101,100,88));
list.add(new Student(3,"王五","二班",99,84,94,106,96,108));
list.add(new Student(4,"张三峰","一班",89,95,76,96,104,92));
list.add(new Student(5,"李思娴","一班",80,121,71,90,128,60));
//传递到方法中 得到数组数据
String content[][]=contentlist(list);
//测试方法
for (int i = 0; i < content.length; i++) {
for (int j = 0; j < 11; j++) {
System.out.print(content[i][j]+"\t");
}
System.out.println();
}
//创建一个Excel
HSSFWorkbook workbook=new HSSFWorkbook();
//创建一个工作表
HSSFSheet sheet=workbook.createSheet("sheet1");
//创建标题列
String title[]={"班级名称","学生学号","中文名称","期中语文","期中数学","期中英语","期中合计","期末语文","期末数学","期末英语","期末合计"};
//得到固定的第一行
HSSFRow row_title=sheet.createRow(0);
//循环行设置表格标题 列值
for (int i = 0; i < title.length; i++) {
//得到列
HSSFCell cell_title=row_title.createCell(i);
//设置列值
cell_title.setCellValue(title[i]);
//给单元格设置样式 给标题栏设置样式 红色字体、加粗、天蓝色背景
cell_title.setCellStyle(CreateCellStyle1(workbook));
//设置两行通栏
Region region = new Region(0,(short)i,1,(short)i);
sheet.addMergedRegion(region);
}
//--------------------------------------------------
//循环数组数据设置到行内
for (int i = 0; i < content.length; i++) {
//创建行 从第三行开始创建
HSSFRow row_content=sheet.createRow(i+2);
for (int j = 0; j < 11; j++) {
//得到行了 开始创建列
HSSFCell cell_content=row_content.createCell(j);
//判断6 和 10 输出公式
if(j==6||j==10){
//设值到单元格中
cell_content.setCellFormula(content[i][j]);
}else if(j==3||j==4||j==5||j==7||j==8||j==9){
//设值到单元格中
cell_content.setCellValue(Integer.parseInt(content[i][j]));
}else{
//设值到单元格中
cell_content.setCellValue(content[i][j]);
}
}
}
//-----------------------------------------------------------
//创建底部 动态创建最后一行
HSSFRow row_total=sheet.createRow(sheet.getLastRowNum()+1);
//定义底部数据
String total_footer[]={"总计","","","","","","","","","",""};
//循环数据
for (int i = 0; i < total_footer.length; i++) {
//创建列
HSSFCell cell_total=row_total.createCell(i);
//判断输出公式
if(i<3){
cell_total.setCellValue(total_footer[i]);
//设置底部样式
cell_total.setCellStyle(CreateCellStyle2(workbook));
}else{//输出公式
//得到序列
String index=getExcelColumnLabel(i);
cell_total.setCellFormula("sum("+index+"3:"+index+"7)");
//设置底部样式
cell_total.setCellStyle(CreateCellStyle2(workbook));
}
}
//读写文件出本地磁盘
try {
OutputStream stream = new FileOutputStream("D:\\poiExicel.xls");
workbook.write(stream);
System.out.println("操作成功!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(1)、以上list中的数据可以从数据库查询,
(2)、contentlist这是一个方法,用来整合list中对象的数据,还有一点是在数组中加入了公式,导出时可以直接计算,并且要用sum(D3:F3),其中单元格数据必须是整型,不然得出结果是0
//循环数据整合到数组中
public static String[][] contentlist(List list){
//定义数组大小
String content[][]=new String[list.size()][11];
//循环list
for (int i = 0; i < list.size(); i++) {
Student s = (Student) list.get(i);
content[i][0]=s.getSid()+"";
content[i][1]=s.getSname();
content[i][2]=s.getCname();
content[i][3]=s.getStartYuWen()+"";
content[i][4]=s.getStartSuXue()+"";
content[i][5]=s.getStartYingYu()+"";
content[i][6]="sum(D"+(i+3)+":F"+(i+3)+")";
content[i][7]=s.getEndYuWen()+"";
content[i][8]=s.getEndSuXue()+"";
content[i][9]=s.getEndYingYu()+"";
content[i][10]="sum(H"+(i+3)+"+I"+(i+3)+"+J"+(i+3)+")";
}
return content;
}
(3)、下面这两个方法是怎样获取Excel表格中的序列号,比如A、B、C…
方法一
//得到工作表的序列名
public static String getExcelColumnLabel(int num) {
String temp = "";
double i = Math.floor(Math.log(25.0 * (num) / 26.0 + 1) / Math.log(26)) + 1;
if (i > 1) {
double sub = num - 26 * (Math.pow(26, i - 1) - 1) / 25;
for (double j = i; j > 0; j--) {
temp = temp + (char) (sub / Math.pow(26, j - 1) + 65);
sub = sub % Math.pow(26, j - 1);
}
} else {
temp = temp + (char) (num + 65);
}
return temp;
}
方法二
public static String getExcelColumnLabels(int iCol) {
String strCol = "";
int baseCol = 65 + iCol;
if (baseCol > 90) {
// 十位位置
int i2 = 0;
if ((baseCol - 90) / 26 > 0) {
i2 = 65 + ((baseCol - 90 - 1) / 26);
} else {
i2 = 65;
}
// 个位位置
int i1 = ((baseCol - 90 - 1) % 26);
i1 = 65 + i1;
strCol = String.valueOf((char) i2) + String.valueOf((char) i1);
} else {
strCol = String.valueOf((char) baseCol);
}
return strCol;
}
(4)、给excel设置样式用HSSFCellStyle,并添加到单元格
样式一
//头部样式 红色字体、加粗、天蓝色背景
public static HSSFCellStyle CreateCellStyle1(HSSFWorkbook workbook){
//得到样式
HSSFCellStyle style=workbook.createCellStyle();
//得到字体
HSSFFont font=workbook.createFont();
font.setFontName("隶书");//字型
font.setColor(HSSFColor.RED.index);//字体样式
font.setBoldweight(font.BOLDWEIGHT_NORMAL);//加粗
//给style设置font
style.setFont(font);
//填充颜色
style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//设置垂直加水平居中
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
//返回style
return style;
}
样式二
//底部样式 背景色为黄色
public static HSSFCellStyle CreateCellStyle2(HSSFWorkbook workbook){
//得到样式
HSSFCellStyle style=workbook.createCellStyle();
//填充颜色
style.setFillForegroundColor(HSSFColor.YELLOW.index);
style.setFillPattern(HSSFCellStyle.BORDER_DASHED);
//返回style
return style;
}
*(5)、这一步我上面没有写,是另外添加的,下面这串代码是要在服务器跑起来在页面操作,只要替换掉主方法中的"读写文件出本地磁盘"的代码,就有像网上下载文件的自定义位置导出Excel表格
// 将excel的数据写入文件
ByteArrayOutputStream fos = null;
byte[] retArr = null;
try {
fos = new ByteArrayOutputStream();
wb.write(fos);
retArr = fos.toByteArray();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
OutputStream os = res.getOutputStream();
try {
res.reset();
res.setHeader("Content-Disposition",
"attachment; filename=agent_book.xls");// 要保存的文件名
res.setContentType("application/octet-stream; charset=utf-8");
os.write(retArr);
os.flush();
} finally {
if (os != null) {
os.close();
}
}
替换
3、效果图