当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统、银行系统)。或者是:我们已经习惯用Excel打印。这样在我们实际的开发中,很多时候需要实现导入、导出Excel的应用。
目前,比较常用的实现Java导入、导出Excel的技术有两种Jakarta POI和Java Excel
下面我就分别讲解一下如何实现导出Excel。
Jakarta POI 是一套用于访问微软格式文档的Java API。Jakarta POI有很多组件组成,其中有用于操作Excel格式文件的HSSF和用于操作Word的HWPF,在各种组件中目前只有用于操作Excel的HSSF相对成熟。官方主页http://poi.apache.org/index.html,API文档http://poi.apache.org/apidocs/index.html
2.1 环境配置
2.1.1下载jar
官方下载:http://poi.apache.org/download.html这里可以下载到它的最新版本和文档,目前最新版本是3.7,这里使用比较稳定的3.6版。
2.1.2加入jar包
将根目录下的poi-3.6-20091214.jar和Lib目录下三个通用包 commons-logging-1.1.jar junit-3.8.1.jar log4j-1.2.13.jar拷贝到项目的Lib下
2.2 Jakarta POI HSSF API组件
HSSF(用于操作Excel的组件)提供给用户使用的对象在rg.apache.poi.hssf.usermodel包中,主要部分包括Excel对象,样式和格式,还有辅助操 作。有以下几种对象:
2.3 基本操作步骤
首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(HSSFSheet)组成,一个sheet是由多个row(HSSFRow)组成,一个row是由多个cell(HSSFCell)组成。基本操作步骤:
1、用HSSFWorkbook打开或者创建“Excel文件对象”
2、用HSSFWorkbook对象返回或者创建Sheet对象
3、用Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象读写。
前台代码如下:
<input type="hidden" name="export_json" id="export_json">
//查询
function doSearch(){
var obj = new Object();
obj.audit_flag = $("#search_type").val();
obj.audit_type = $("#audit_type").val();
obj.province = $('#addr_province option:selected').val();
obj.city = $('#addr_city option:selected').val();
obj.area = $('#addr_area option:selected').val();
obj.s_audit_flag = $("#audit_flag").val();
obj.duty_year = $("#duty_year").val();
obj.duty_num = $("#duty_num").val();
obj.user_name = $("#user_name").val();
obj.input_time_start = $("#input_date0").val();
obj.input_time_end = $("#input_date1").val();
obj.execute_remark_type = $("#execute_remark_type").val();
var obj1 = new Object();
obj1.postDate = $.toJSON(obj);
$("#export_json").val($.toJSON(obj));
$("#gridtable").jqGrid('setGridParam',{
url:"<%=request.getContextPath()%>/duty_execute/listdata.do",
postData:obj1,
page:1
}).trigger("reloadGrid");
return true;
}
//导出
function exportExcel(){
window.location.href = "<%=request.getContextPath()%>/duty_execute/toExcel.do?postDate="+$("#export_json").val()+"&datestr="+new Date().getTime();
}
下面来看一个动态生成Excel文件的代码:
package com.syrjbase;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
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.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;
import org.springframework.web.servlet.view.document.AbstractExcelView;
import com.sun.star.table.CellRangeAddress;
import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;
import com.syrjbase.business.duty_execute.DutyExecute;
public class ViewDutyExecuteExcel extends AbstractExcelView{
@SuppressWarnings({ "deprecation", "unchecked" })
@Override
protected void buildExcelDocument(Map map,
HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response)
throws Exception {
HSSFSheet sheet = workbook.createSheet("list");
sheet.setDefaultColumnWidth((short) 12);
sheet.addMergedRegion(new Region(0,(short)0,0,(short)3));
HSSFRow rowT = sheet.createRow(0);
HSSFCell cellT = rowT.createCell((short)0);
cellT.setEncoding(HSSFCell.ENCODING_UTF_16);
cellT.setCellValue("《任务执行情况审核》");
HSSFCellStyle style = workbook.createCellStyle(); // 样式对象
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short) 18);// 设置字体大小
cellT.setCellStyle(style);
getCell(sheet, 1, 0).setCellValue("任务编码");
getCell(sheet, 1, 1).setCellValue("点位编码");
getCell(sheet, 1, 2).setCellValue("省份");
getCell(sheet, 1, 3).setCellValue("负责人");
getCell(sheet, 1, 4).setCellValue("采样日期");
getCell(sheet, 1, 5).setCellValue("总站审核结果");
getCell(sheet, 1, 6).setCellValue("审核内容");
List<DutyExecute> list = (List<DutyExecute>) map.get("execlInfo");
for (short i = 0; i < list.size(); i++) {
DutyExecute info = list.get(i);
HSSFRow sheetRow = sheet.createRow(i+2);
sheetRow.createCell((short)0).setCellValue(info.getDuty_num());
sheetRow.createCell((short)1).setCellValue(info.getPoint_num());
sheetRow.createCell((short)2).setCellValue(info.getProvince());
sheetRow.createCell((short)3).setCellValue(info.getPerson1());
sheetRow.createCell((short)4).setCellValue(info.getInput_date());
sheetRow.createCell((short)5).setCellValue(info.getExecute_remark_type());
sheetRow.createCell((short)6).setCellValue(info.getCompany_name());
}
String filename = "《任务执行情况审核》.xls";//设置下载时客户端Excel的名称
filename = encodeFilename(filename, request);//处理中文文件名
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=" + filename);
OutputStream ouputStream = response.getOutputStream();
workbook.write(ouputStream);
ouputStream.flush();
ouputStream.close();
}
private String encodeFilename(String filename, HttpServletRequest request) {
/**
* 获取客户端浏览器和操作系统信息
* 在IE浏览器中得到的是:User-Agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; Alexa Toolbar)
* 在Firefox中得到的是:User-Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.7.10) Gecko/20050717 Firefox/1.0.6
*/
String agent = request.getHeader("USER-AGENT");
try {
if (null != agent && -1 != agent.indexOf("MSIE") || null != agent
&& -1 != agent.indexOf("Trident")) {
String newFileName = URLEncoder.encode(filename, "UTF-8");
newFileName = StringUtils.replace(newFileName, "+", "%20");
/*if (newFileName.length() > 150) {
newFileName = new String(filename.getBytes("GB2312"), "ISO8859-1");
newFileName = StringUtils.replace(newFileName, " ", "%20");
}*/
return newFileName;
}
if ((agent != null) && (-1 != agent.indexOf("Mozilla")))
return MimeUtility.encodeText(filename, "UTF-8", "B");
return filename;
} catch (Exception ex) {
return filename;
}
}
}
后台代码如下:
//导出Excel
@SuppressWarnings("unchecked")
@RequestMapping(value = "/toExcel")
public ModelAndView toExcel(Model model, HttpServletRequest request) {
String str = request.getParameter("postDate");
if(Common.isNullString(str)){
str = "{}";
}
DutyExecute search = JSON.parseObject(str, DutyExecute.class);
DutyExecute queryinfo = new DutyExecute();
this.addConditions(search, queryinfo);
Map map = new HashMap();
List<DutyExecute> execlInfo = dutyExecuteService.getDutyExcelList(queryinfo);
map.put("execlInfo", execlInfo);
for(int i = 0;i < execlInfo.size(); i++){
DutyExecute execute = execlInfo.get(i);
if(null != execute.getExecute_remark_type() && execute.getExecute_remark_type().equals("【不合格】")){
List<Map<String,String>> audit_baseinfo = dutyExecuteService.getCodeName(execute.getAudit_baseInfo());
String a = "";
for(Map m : audit_baseinfo){
Set<String> sets = m.keySet();
Iterator it = sets.iterator();
while(it.hasNext()){
a = a + m.get(it.next());
}
}
List<Map<String,String>> audit_picture =dutyExecuteService.getCodeNamey(execute.getAudit_picture());
String b = "";
for(Map m : audit_picture){
Set<String> sets = m.keySet();
Iterator it = sets.iterator();
while(it.hasNext()){
b = b + m.get(it.next());
}
}
List<Map<String,String>> audit_simple =dutyExecuteService.getCodeNamee(execute.getAudit_simple());
String c = "";
for(Map m : audit_simple){
Set<String> sets = m.keySet();
Iterator it = sets.iterator();
while(it.hasNext()){
c = c + m.get(it.next());
}
}
List<Map<String,String>> audit_complate =dutyExecuteService.getCodeNames(execute.getAudit_complate());
String d = "";
for(Map m : audit_complate){
Set<String> sets = m.keySet();
Iterator it = sets.iterator();
while(it.hasNext()){
d = d + m.get(it.next());
}
}
String s = a + " " + b + " " + c + " " + d;
execute.setCompany_name(s);
System.out.println(s);
}
}
return new ModelAndView(new ViewDutyExecuteExcel(), map);
}
到这里基本就完成了Excel导出功能,不好的地方希望大家能给出好的意见,第一次做,很多地方还需要学习。