用途:由于ERP系统中要录入很多相关数据,比如每次集团订货会要准备的订货会商品。。。到最后的生产物料,不可能全部通过系统操作界面一个一个手工录入,这样也容易出错。解决的办法是通过系统做好一个Excel模板并下载下来,然后把事先做好的数据放到excel模板中,最后通过系统导入功能导入到数据库表中。
操作界面有:
1.制定正确的Excel模板:
2.导入Excel数据:
实现过程:(我以导入商品资料为例)
1.制定Excel模板:
制定模板的作用是保存要选用的模板名称,相应的处理类字符串(主要操作Manager),处理excel时的明细字段处理类字符串等信息。如上图所示,选用“商品处理类(尺码组)”,各个明细处理类有“单元格处理类(直接读取Excel中cell的值并原值返回),单位处理类。。。)。
保存功能很简单,这里就不说了,接下来说说其中几个处理类的实现。
比如prodExcelProcess(商品处理类):
类图:
IExcelProcess.class
public interface IExcelProcess {
public List execute(ExcelContext context) throws Exception ;
}
SimpleExcelProcess.class
public abstract class SimpleExcelProcess implements IExcelProcess {
IDao dao = null;
NameManager nameManager = null;
public IDao getDao() {
return dao;
}
public void setDao(IDao dao) {
this.dao = dao;
}
public NameManager getNameManager() {
return nameManager;
}
public void setNameManager(NameManager nameManager) {
this.nameManager = nameManager;
}
}
ProdExcelProcess.class
public class ProdExcelProcess extends SimpleExcelProcess {
...
public List execute(ExcelContext context) throws Exception {
List errorList = new ArrayList();
try {
System.out.println("开始导入前的预处理");
List<RowBean> prodlist = processResults(context,context.getResults(),errorList);
if (errorList.size() == 0) {
for(RowBean bean:prodlist){
System.out.println("保存商品:"+bean.prod.getCode());
Integer tbsprodid=(Integer)dao.addSave(bean.prod);
Operators os=new Operators();
getProdManager(context).saveDetail(tbsprodid, bean.prod.getCode(),bean.colorlist, bean.sizelist, new ArrayList(), os);
dao.execute(os);
}
}
} catch (Exception e) {
Map errorMap = new HashMap();
errorMap.put("type", "数据错误");
errorMap.put("rows", "");
errorMap.put("keyvalue", "");
errorMap.put("message", "执行Hibernat批量保存的时候发生错误");
errorList.add(errorMap);
SystemLogger.error(e.getMessage(), e);
}
return errorList;
}
...
}
其中要传入读取Excel包装后的ExcelContext,
ExcelContext.class
public class ExcelContext {
Tsysexcel master;
List dtllist;
ExcelForm form;
HttpServletRequest request;
ClientSession client;
Map vars = new HashMap();
List results=new ArrayList();
IExcelProcess excelProcess;
CRUDOperatorImpl springBean;
...
}
类中的的results集合是用来读取excel中每行数据,然后存起来。读取excel数据的代码如下:
public List read(ExcelContext context) throws Exception {
List errorList = new ArrayList();
InputStream stream = context.getForm().getFormFile().getInputStream();//上传得excel
if (stream != null) {
Workbook workbook = null;
try {
workbook = Workbook.getWorkbook(stream);
} catch (Exception e) {
Map errorMap = new HashMap();
errorMap.put("type", "系统错误");
errorMap.put("message", "读取Excel文件发生错误");
errorList.add(errorMap);
SystemLogger.error(e.getMessage(), e);
return errorList;
}
Sheet sheet = workbook.getSheet(0);//因为只有一个excel页面
if (sheet != null) {
String code = ExcelUtil.getContent(sheet, 0, 1);//读取excel中的第一行第二列的数据,为编号
Tsysexcel master = getMaster(code);//从数据库中查找前面配好的Excel模板
if (master == null) {
Map errorMap = new HashMap();
errorMap.put("type", "系统错误");
errorMap.put("message", "Excel配置不存在");
errorList.add(errorMap);
}
if (errorList.size() > 0) {
return errorList;
}
String processstr = master.getProcessclass();
IExcelProcess process = (IExcelProcess) WebUtil.getBean(
processstr, context.getRequest());
if (StringUtil.isNotBlank(master.getSpringname())) {
if (master.getSpringname().indexOf(".") < 0) {
Object bean = WebUtil.getBean(master.getSpringname(),
context.getRequest());
if (bean != null) {
CRUDOperatorImpl springbean = null;
springbean = (CRUDOperatorImpl) bean;
context.setSpringBean(springbean);
}
}
}
context.setMaster(master);
context.setExcelProcess(process);
List dtllist = getDtllist(master.getTsysexcelid());
context.setDtllist(dtllist);
readEx(sheet, context);
List results = new ArrayList();
int beginRow = getBeingRow();
for (int row = beginRow; row < sheet.getRows(); row++) {
Map rowMap = new HashMap();
rowMap.put("rowid", String.valueOf(row + 1));
boolean notBlankRow = StringUtils.isNotBlank(ExcelUtil
.getContent(sheet, row, 0));
int plugCol = 0;
for (int i = 0; notBlankRow && i < dtllist.size(); i++) {
Tsysexceldtl detail = (Tsysexceldtl) dtllist.get(i);
IExcelField processor = (IExcelField) WebUtil.getBean(
detail.getFieldprocess(), context.getRequest());
Map valueMap = new HashMap();
Map errorMap = null;
try {
errorMap = processor.importValue(context, detail,
sheet, row, valueMap, plugCol);
if (processor instanceof SizeExcelField) {
plugCol = processor.getCol(context, detail)
+ plugCol - 1;
}
if (errorMap != null && errorMap.size() > 0) {
errorList.add(errorMap);
}
} catch (Exception pe) {
SystemLogger.error(pe.getMessage(), pe);
errorMap = new HashMap();
errorMap.put("type", "系统错误");
errorMap.put("message", "读取Excel 字段发生错误:"
+ detail.getFieldtitle());
errorList.add(errorMap);
}
// 处理.
rowMap.putAll(valueMap);
}
if (notBlankRow) {
results.add(rowMap);
}
}
context.setResults(results);
}
}
return errorList;
}
ExcelUtil.java中取第x行第x列的函数:
public static String getContent(Sheet sheet, int row, int col) {
if (col < 0)
return "";
String result = "";
if (sheet != null) {
Cell[] rowcell = sheet.getRow(row);
Object[] obj = (Object[]) rowcell;
if (obj == null)
return "";
if (obj.length < col + 1)
return "";
Object xxx = obj[col];
if (xxx == null)
return "";
String temp = ((Cell) xxx).getContents();
result = StringUtil.notNull(temp);
}
return result;
}