excel 通用导入

通用的POI导入Excel解决方案
引言:在项目中,经常免不了要导入、导出Excel,导出Excel稍微简单点,制作一张模板,然后将查询之后的数据写入到模板中即可,导出程序可以做到一次写好,基本上就可以通用。

但导入Excel相对麻烦点,一般情况下,导入的程序无法通用的主要原因是:对于不同的导入模板,字段field与单元格cellRef的映射关系是不相同的,这就导致对每一个导入模板都要去写一套相似的代码;我们应该想办法解决这个问题,减少每次导入Excel时都去拷贝粘贴相同的代码。

问题的关键是解决:字段field与单元格cellRef的映射关系;

如何解决呢?将这个映射关系从程序中抽取出来。

如何抽取呢?曾经跟一些同事、朋友聊天时谈到这个话题,

有的建议将这个映射关系写在Excel单元格里面,并且设置将单元格隐藏;

有的建议用2个相似的excel模板文件,将映射关系放在A模板文件中,B模板文件提供给用户导入数据;

有的建议将映射关系单独写在xml文件中;。。。。

经过再三权衡,最终我选择使用方法3,即将映射关系写在XML配置文件中。

通常情况下,我们的导入模板是大致为这样的:


(1) 有颜色的单元格是需要被导入到后台的有用信息,且单元格中的单词即为field信息

(2) 橙色单元格为只填写/读取一次的数据。

(3) 蓝色单元格为循环填写/读取的数据,A10单元格中,End表示读取到这里时,循环结束。

所以我们字段field与单元格cellRef映射信息可以是这样子的:

<?xml version="1.0" encoding="UTF-8"?>

<excelImport>

<onceImport>

<![CDATA[

C3 = ORDER_NBR, H3 = CUST_NAME,

N3 = CUST_LINK_INFO, C4 = CUST_ID,

H4 = CUST_ADDR, N4 = ONCE_TYPE,

C5 = CONTACT_ID, H5 = CUST_FILE,

N5 = LOOP_TYPE, C6 = PRO_NAME,

H6 = OPPO_ORDER_NBR, N6 = COOPERATE_MODE,

C11 = AUD_MANGER, N11 = BM,

C12 = ORDER_COMMENT

]]>

</onceImport>

<repeatImport>

<![CDATA[

A9 = STRNUM, B9 = FRI_AREA,

C9 = OPP_A, D9 = SEC_AREA,

E9 = OPP_B, F9 = NUM,

G9 = SERV_NBR, H9 = SPEED,

I9 = FRI_ADDR, J9 = PORT_TYPE_A,

K9 = FRI_LINK_A, L9 = SEC_ADDR,

M9 = PORT_TYPE_B, N9 = FRI_LINK_B,

O9 = APPLY_INFO, P9 = ORDER_DATE,

Q9 = HIRE_TIME, R9 = DISCOUNT_MID,

S9 = BILL_DATE, T9 = OLD_BILL_DATE,

U9 = LINE_COMMENT

]]>

<endCode>End</endCode>

</repeatImport>

</excelImport>


(1) <onceImport/> 表示只需要一次导入的数据,字段field与单元格cellRef的映射关系写在CDATA区中。

(2) <repeatImport/>表示需要循环导入的数据,字段field与单元格cellRef的映射关系写在CDATA区中。<endCode/>表示循环终止的字符。

下面说一下,根据这个XML描述文件,我们需要从Excel中解析出什么样的数据格式来:

/**

* 读取导入的Excel的内容

* 模板要求:

* (1)开始重复行与End行 有且只能有 一空行

*/

public class ExcelImportUtil

{

/**

* 读取导入的Excel的文件内容

* @param xmlFile 描述被导入的Excel的格式的XML文件

* @param importExcelStream 被导入的XML文件

* @return Excel中需要导入的数据

*/

public static ExcelData readExcel(String xmlFile, InputStream importExcelStream) throws ExcelImportException

{}

}

/**

* Excel导入的信息

*/

import java.util.List;

import java.util.Map;

public class ExcelData

{

// 一次导入的数据,key就是field,一个ImportCellDesc描述了一个单元格(field,value,单元格名称)

private Map<String, ImportCellDesc> onceData;

// 重复导入的数据

private List<Map<String, ImportCellDesc>> repeatData;

// setter/getter

}

/**

* 单元格的描述信息

* (1)数据格式校验时,可以精确定位到某个单元格。

*/

public class ImportCellDesc

{

/**

* 引用的单元格;如:A3

*/

private String cellRef;

/**

* 单元格的对应数据库的字段名称;

* 如:fieldName = "username"

*/

private String fieldName;

/**

* 字段值,如:张三

*/

private String fieldValue;

// setter/getter

}


调用代码:

ExcelData excelData = ExcelImportUtil.readExcel(xmlFile, importExcelStream);

然后在这个基础上,我们可以对数据进行一些操作,如:数据校验,插入数据。。。

其中数据校验时,如果数据不合法,给用户的提示信息可以精确指定某个单元格的数据不合法。(如:提示信息为:A3单元格数据不合法!)

注:使用了如下第三方JAR包:

Jdom :解析XML描述文件

POI3.0 : 读取Excel文件

Xml描述文件,必须放在cn.zhaoql.excelimport.xml这个包里面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值