POI导出到Excel的简单例子

最近项目中要将数据导出到Excel,没做过,在网上搜了些资料,简单实现了这个功能。项目环境是spring+struts+mybatis。我将功能放在了action里,在页面使用表单提交到后台,如果有需要,可以传递一些参数供查询数据库使用,在action里调用业务层方法查询封装数据。

对于大数据量的导出,没有经过测试,我也是初次使用POI,还没有深入研究,这里仅供参考。

先看实现效果


简单表格如下


复杂表格如下


下面看代码。如果表格简单,表头只有一行的话,可以使用下面的工具类,封装好数据,直接调用即可导出到excel。

package org.wusq.ssx.component.poi;

import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.hssf.util.HSSFColor;

/**
 * 导出EXCEL工具类,适用于单行表头的表格
 * @author wusq
 * @since 2011-06-20
 */
public class ExportExcelUtils {
	
	/**
	 * 导出Excel的方法
	 * @param title excel中的sheet名称
	 * @param headers 表头
	 * @param columns 表头对应的数据库中的列名
	 * @param result 结果集
	 * @param out 输出流
	 * @param pattern 时间格式
	 * @throws Exception
	 */
	public static void exportExcel(String title, String[] headers, String[] columns, List<LinkedHashMap<String, Object>> result, OutputStream out, String pattern) throws Exception{
		// 声明一个工作薄
		HSSFWorkbook workbook = new HSSFWorkbook();
		// 生成一个表格
		HSSFSheet sheet = workbook.createSheet(title);
		// 设置表格默认列宽度为20个字节
		sheet.setDefaultColumnWidth(20);
		
		
		// 生成一个样式
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置这些样式
		style.setFillForegroundColor(HSSFColor.GOLD.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 生成一个字体
		HSSFFont font = workbook.createFont();
		font.setColor(HSSFColor.VIOLET.index);
		//font.setFontHeightInPoints((short) 12);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 把字体应用到当前的样式
		style.setFont(font);
		
		// 指定当单元格内容显示不下时自动换行
		style.setWrapText(true);
		
		/*
		 
		 以下可以用于设置导出的数据的样式
		  
		// 生成并设置另一个样式
		HSSFCellStyle style2 = workbook.createCellStyle();
		style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 生成另一个字体
		HSSFFont font2 = workbook.createFont();
		font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		// 把字体应用到当前的样式
		style2.setFont(font2);
		// 声明一个画图的顶级管理器
		HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
		
		
		// 定义注释的大小和位置,详见文档
		HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
		// 设置注释内容
		comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
		// 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
		comment.setAuthor("leno");*/
		
		
		// 产生表格标题行
		HSSFRow row = sheet.createRow(0);
		for (int i = 0; i < headers.length; i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellStyle(style);
			HSSFRichTextString text = new HSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}
		// 遍历集合数据,产生数据行
		if(result != null){
			int index = 1;
			for(LinkedHashMap<String, Object> m:result){
				row = sheet.createRow(index);
				int cellIndex = 0;
				for(String s:columns){
					HSSFCell cell = row.createCell(cellIndex);
					//cell.setCellStyle(style2);
					HSSFRichTextString richString = new HSSFRichTextString(m.get(s) == null ? "" : m.get(s).toString());
					//HSSFFont font3 = workbook.createFont();
					//font3.setColor(HSSFColor.BLUE.index);
					//richString.applyFont(font3);
					cell.setCellValue(richString);
					cellIndex++;
				}
				index++;
			}	
		}
		workbook.write(out);
	}
}

测试类继承ActionSupport。如果表头比较复杂,有多行,则需单独处理,见测试类的moreHead()方法。

package org.wusq.ssx.component.poi;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;

@Controller
public class ExportExcelAction extends ActionSupport{

	private static final long serialVersionUID = 2165773254718823136L;
	
	/**
	 * 测试单行表头的表格
	 * @return
	 */
	public String oneHead(){
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setContentType("octets/stream");
			response.addHeader("Content-Disposition","attachment;filename=test.xls");
			OutputStream out = response.getOutputStream();
			
			//此处为模拟数据,实际应用从数据库中查出
			List<LinkedHashMap<String, Object>> result = new ArrayList<LinkedHashMap<String, Object>>();
			LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
			map.put("ID", "1");
			map.put("USER", "wusq");
			map.put("PASS", "000000");
			result.add(map);
			
			String[] headers = {"ID", "用户名", "密码"};
			String[] columns = {"ID", "USER", "PASS"};
			ExportExcelUtils.exportExcel("用户表", headers, columns, result, out, "");
			out.close();
		} catch (Exception e) {
			//e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 测试多行表头
	 * @return
	 */
	public String moreHead(){
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("octets/stream");
		response.addHeader("Content-Disposition","attachment;filename=test.xls");
		OutputStream out = null;
		HSSFWorkbook workbook = new HSSFWorkbook();
		try {
			out = response.getOutputStream();
			HSSFSheet sheet = workbook.createSheet();
			List<String> jsdj = new ArrayList<String>();
			jsdj.add("一级");
			jsdj.add("二级");
			
			List<String> xzdj = new ArrayList<String>();
			xzdj.add("国道");
			xzdj.add("省道");
			
			int number = 2 + jsdj.size() + xzdj.size();

			// 给工作表列定义列宽(实际应用自己更改列数)
			for (int i = 0; i < number; i++) {
				sheet.setColumnWidth(i, 3000);
			}
			
			// 创建单元格样式
			HSSFCellStyle cellStyle = workbook.createCellStyle();

			// 指定单元格居中对齐
			cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

			// 指定单元格垂直居中对齐
			cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			// 指定当单元格内容显示不下时自动换行
			cellStyle.setWrapText(true);
			cellStyle.setFillForegroundColor(HSSFColor.GOLD.index);
			
			// 设置列头
			HSSFRow row0 = sheet.createRow(0);

			HSSFCell cell0 = row0.createCell(0);
			cell0.setCellStyle(cellStyle);
			cell0.setCellValue(new HSSFRichTextString("所属年份"));

			HSSFCell cell1 = row0.createCell(1);
			cell1.setCellStyle(cellStyle);
			cell1.setCellValue(new HSSFRichTextString("隐患公里"));

			HSSFCell cell2 = row0.createCell(2);
			cell2.setCellStyle(cellStyle);
			cell2.setCellValue(new HSSFRichTextString("技术等级"));
			
			HSSFCell cell3 = row0.createCell(2 + jsdj.size());
			cell3.setCellStyle(cellStyle);
			cell3.setCellValue(new HSSFRichTextString("行政等级"));

			HSSFRow row1 = sheet.createRow(1);
			HSSFCell row1Cell = null;
			int m = 0;
			int n = 0;
			for(int i = 2; i < 2 + jsdj.size() + xzdj.size(); i++){
				if(i < 2 + jsdj.size()){
					row1Cell = row1.createCell(i);
					row1Cell.setCellStyle(cellStyle);
					row1Cell.setCellValue(new HSSFRichTextString(jsdj.get(m)));
					m++;
				}else{
					row1Cell = row1.createCell(i);
					row1Cell.setCellStyle(cellStyle);
					row1Cell.setCellValue(new HSSFRichTextString(xzdj.get(n)));
					n++;
				}
				
			}
			//合并第一行到第二行的第一列
			sheet.addMergedRegion(new Region(0, (short) 0, 1, (short) 0));
			
			//合并第一行到第二行的第二列
			sheet.addMergedRegion(new Region(0, (short) 1, 1, (short) 1));
			
			// 合并第一行的第三列到第指定的列
			int a = 1 + jsdj.size();
			sheet.addMergedRegion(new Region(0, (short) 2, 0, (short) a));
			
			int b = 1 + jsdj.size() + xzdj.size();
			sheet.addMergedRegion(new Region(0, (short) (a + 1), 0, (short) b));
			
			//此处为模拟数据,实际应用从数据库中查出
			List<LinkedHashMap<String, Object>> result = new ArrayList<LinkedHashMap<String, Object>>();
			LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
			map.put("SSNF", "2011");
			map.put("YHGL", "100");
			map.put("YJ", "10");
			map.put("EJ", "20");
			map.put("GD", "30");
			map.put("SD", "40");
			result.add(map);
			
			HSSFRow row = null;
			HSSFCell rowCell = null;
			for(int i = 0; i < result.size(); i++ ){
				LinkedHashMap<String, Object> lhm = result.get(i);
				row = sheet.createRow(i + 2);
				rowCell = row.createCell(0);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("SSNF").toString()));
				
				rowCell = row.createCell(1);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("YHGL").toString()));
				
				rowCell = row.createCell(2);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("YJ").toString()));
				
				rowCell = row.createCell(3);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("EJ").toString()));
				
				rowCell = row.createCell(4);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("GD").toString()));
				
				rowCell = row.createCell(5);
				rowCell.setCellValue(new HSSFRichTextString(lhm.get("SD").toString()));
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			workbook.write(out);
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}


测试页面使用了两个表单提交。

<body>
   	 测试导出到excel功能(单行表头) <br>
    <form id="form1" name="form1" action="oneHead.do" method="post">
    	<input type="submit" name="submit" value="导出到Excel">
    </form>
          测试导出到excel功能(复杂表头) <br>
    <form id="form2" name="form2" action="moreHead.do" method="post">
    	<input type="submit" name="submit" value="导出到Excel">
    </form>
  </body>

注意配置好struts2的跳转路径,一般不需要设置跳转页面。

<struts>
	<package name="poi" namespace="/" extends="struts-default">
		<action name="oneHead" class="exportExcelAction" method="oneHead">
        </action>
        <action name="moreHead" class="exportExcelAction" method="moreHead">
        </action>
	</package>
</struts>

异常处理可能不太合理,如果后台程序出现异常,对于简单表格,将导出一个空的excel文件,对于复杂表格,只导出了表头。

POI的jar包可以去官网下载,我用的3.7版本,引入poi-3.7-20101029.jar即可。

本文原先发表于本人的另一博客,后弃之不用,特转移到新博客来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值