jeecg中导入导出excel文件使用了jeecg团队自己开发的一个easypoi库,所以使用起来非常简单,以我项目中导入黑名单列表功能为例:
-
在实体中增加注解
先增加类的注解:
@ExcelTarget("blackListEntity")
public class BlackListEntity implements java.io.Serializable {
再增加字段注解:
/**手机号码*/
@Excel(name="手机号码")
private Long msisdn;
/**状态*/
@Excel(name="状态",replace = {"启用_1","禁用_0"})
private Integer state;
在jsp界面中使用upload标签,如下:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@include file="/context/mytags.jsp"%>
<!DOCTYPE html>
<html>
<head>
<title>Excel导入</title>
<t:base type="jquery,easyui,tools"></t:base>
</head>
<body style="overflow-y: hidden" scroll="no">
<t:formvalid formid="formobj" layout="div" dialog="true" beforeSubmit="upload">
<fieldset class="step">
<div class="form"><t:upload name="fiels" buttonText="选择要导入的文件" uploader="blackListController.do?importExcel" extend="*.xls;*.xlsx" id="file_upload" formData="documentTitle"></t:upload></div>
<div class="form" id="filediv" style="height: 50px"></div>
</fieldset>
</t:formvalid>
</body>
</html>
在controller中接收上传的文件并调用easypoi的api进行文件的解析就可以了,如下:
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
List<BlackListEntity> allRecords = new ArrayList<BlackListEntity>();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(0);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<BlackListEntity> listBlackList = ExcelImportUtil.importExcelByIs(file.getInputStream(),BlackListEntity.class,params);
allRecords.addAll(listBlackList);
} catch (Exception e) {
logger.error(ExceptionUtil.getExceptionMessage(e));
}finally{
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这样一个导入excel文件的功能就做好了,easypoi会把excel文件中的数据解析成为一个List对象,接下去要怎么处理就跟具体的业务逻揖有关了。
但我们实际开发中往往会遇到这样的需求:客户希望导入失败的信息也能够查看,如这个导入黑名单功能中就要求手机号码不能重复,如果手机号码在数据库中存的话要在导入完成后让用户可以下载错误文件查看哪些号码是导重复了。
我的解决思路大概如下:
-
在service中保存数据时检查号码在数据库中是否已经存在,如果存在则产生一个ErrorMsg类的实例放放到List中
-
对这个List进行循环生成excel文件写入到磁盘中
-
产生一个TSAttachment的实例,也就是往jeecg的附件表中增加一条附件记录,把错误日志当作一个附件保存起来
-
把下载这个附件的链接返回到jsp界面
完整代码如下:
jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@include file="/context/mytags.jsp"%>
<!DOCTYPE html>
<html>
<head>
<title>Excel导入</title>
<t:base type="jquery,easyui,tools"></t:base>
</head>
<body style="overflow-y: hidden" scroll="no">
<t:formvalid formid="formobj" layout="div" dialog="true" beforeSubmit="upload">
<fieldset class="step">
<div class="form"><t:upload name="fiels" buttonText="选择要导入的文件" uploader="blackListController.do?importExcel" extend="*.xls;*.xlsx" id="file_upload" formData="documentTitle"></t:upload></div>
<div class="form" id="filediv" style="height: 50px"></div>
</fieldset>
</t:formvalid>
</body>
</html>
controller
@RequestMapping(params = "importExcel", method = RequestMethod.POST)
@ResponseBody
public AjaxJson importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
List<BlackListEntity> allRecords = new ArrayList<BlackListEntity>();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(0);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<BlackListEntity> listBlackList = ExcelImportUtil.importExcelByIs(file.getInputStream(),BlackListEntity.class,params);
allRecords.addAll(listBlackList);
} catch (Exception e) {
logger.error(ExceptionUtil.getExceptionMessage(e));
}finally{
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
AjaxJson j = this.blackListService.saveBlackLists(allRecords, request);
return j;
}
对应的两个service类(接口我就没贴了,只贴实现类的代码),其中用到了jeecg中的AjaxJson类用来返回json结果
BlackListServiceImpl
public AjaxJson saveBlackLists(List<BlackListEntity> listBlackList, HttpServletRequest request) {
List<BlackListEntity> actualList = new ArrayList<BlackListEntity>();
List<ErrorMsg> errorMsgList = new ArrayList<ErrorMsg>();
long tempCount = 0;
int idx = 0;
for (BlackListEntity blackList : listBlackList) {
idx++;
//判断黑名单号码在数据库中是否存在
tempCount = super.getCountForJdbcParam(GET_COUNT, new String[]{blackList.getMsisdn().toString()});
if (tempCount == 0) {
actualList.add(blackList);
} else {
//创建错误信息,包括行号,错误信息两个字段
ErrorMsg errorMsg = new ErrorMsg();
errorMsg.setNum(idx + 1);
errorMsg.setMsg("手机号码" + blackList.getMsisdn() + "在系统中已经存在");
errorMsgList.add(errorMsg);
}
}
if (!actualList.isEmpty()) {
super.batchSave(actualList);
//产生重新加载黑名单事件
EventEntity event = new EventEntity();
event.setEventId("ReloadBlackListEvent");
super.save(event);
}
AjaxJson j = new AjaxJson();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("successNum", actualList.size());
attributes.put("failNum", errorMsgList.size());
if (!errorMsgList.isEmpty()) {
String downloadHref = this.errorMsgService.saveErrorMsg(errorMsgList, request, attributes);
StringBuilder builder = new StringBuilder("导入完成,但有一些数据导入失败,您可以");
builder.append("<a href=\"").append(downloadHref).append("\">下载错误信息</a>进行查看");
j.setMsg(builder.toString());
} else {
j.setMsg("导入成功");
}
return j;
}
ErrorMsgServiceImpl(用来封装生成错误日志及生成附件记录并返回链接的逻揖):
/**
*
*/
package com.jason.ddoWeb.service.impl.common;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.core.common.service.impl.CommonServiceImpl;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.TemplateExportParams;
import org.jeecgframework.web.system.pojo.base.TSAttachment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jason.ddoWeb.common.model.ErrorMsg;
import com.jason.ddoWeb.service.common.ErrorMsgServiceI;
/**
* 生成错误信息公共service
* @author jasonzhang
*
*/
@Service("errorMsgService")
@Transactional
public class ErrorMsgServiceImpl extends CommonServiceImpl implements
ErrorMsgServiceI {
/* (non-Javadoc)
* @see com.jason.ddoWeb.service.common.ErrorMsgServiceI#saveErrorMsg(java.util.List, javax.servlet.http.HttpServletRequest, java.util.Map)
*/
@Override
public String saveErrorMsg(List<ErrorMsg> errorMsgs,
HttpServletRequest request, Map<String, Object> attributes) {
//把错误信息写入文件
TemplateExportParams params = new TemplateExportParams();
params.setHeadingRows(1);
params.setHeadingStartRow(0);
params.setTemplateUrl("export/template/errormsgtemp.xls");
Map<String,Object> map = new HashMap<String, Object>();
Workbook book = ExcelExportUtil.exportExcel(params, ErrorMsg.class, errorMsgs, map);
String uploadbasepath = ResourceUtil.getConfigByName("uploadpath");
String path = uploadbasepath + "/";// 文件保存在硬盘的相对路径
String realPath = request.getSession().getServletContext().getRealPath("/") + "/" + path;// 文件的硬盘真实路径
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();// 创建根目录
}
String errormsgPath = realPath + "/" + ResourceUtil.getConfigByName("errormsgpath");
file = new File(errormsgPath);
if (!file.exists()) {
file.mkdirs();
}
String fileName = System.currentTimeMillis() + ".xls";
//String filePath = errormsgPath + "/" + fileName;
try {
FileOutputStream fos = new FileOutputStream(errormsgPath + "/" + fileName);
book.write(fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
TSAttachment attachment = new TSAttachment();
attachment.setRealpath("/" + ResourceUtil.getConfigByName("uploadpath") + "/" + ResourceUtil.getConfigByName("errormsgpath") + "/" + fileName);
attachment.setAttachmenttitle(fileName);
attachment.setExtend("xls");
super.save(attachment);
StringBuilder builder = new StringBuilder();
builder.append("commonController.do?viewFile&fileid=").append(attachment.getId());
return builder.toString();
}
}