假设现在要做一个通用的导入方法:
要求:
1.xml的只定义数据库表中的column字段,字段类型,是否非空等条件。
2.excel定义成模板,里面只填写了所需要的数据,有可能数据有问题。
3.在导入的时候就需要对每个excel单元格的数据进行验证。
4.验证完之后,若所有数据正确,那么批量保存。若有一点点错误,就不执行保存操作,并提示错误原因。
思路:
1.完美使用了Map的功能,先将xml中的数据存入map中,怎么存呢?
下面我根据xml文件来具体分析:(为图方便,我只做了字段的非空验证)
user.xml
1. <?xml version="1.0" encoding="UTF-8"?>
2. <excel>
3. <entity name="用户表" code="user" >
4. <column name="状态" code="status" type="String"></column>
5. <column name="端口号" code="port" type="int">
6. <rules>
7. <rule name="nullable" message="端口号不允许为空"></rule>
8. </rules>
9. </column>
10. <column name="IP地址" code="ip" type="String">
11. <rules>
12. <rule name="nullable" message="IP地址不允许为空"></rule>
13. </rules>
14. </column>
15. <column name="密码" code="password" type="String">
16. <rules>
17. <rule name="nullable" message="密码不允许为空"></rule>
18. </rules>
19. </column>
20. <column name="用户名" code="username" type="String"></column>
21. <column name="员工号" code="no" type="String">
22. <rules>
23. <rule name="nullable" message="员工号不允许为空"></rule>
24. <rule name="checkUnique" message="员工号已经存在"></rule>
25. </rules>
26. </column>
27. <column name="头像" code="userImage" type="BLOB"></column>
28. </entity>
29. </excel>
根据xml所做的准备:
准备4个Map:
(1),已知 <entity> 中的name="用户表" ,定义entityMap 来存放实体类的map对象
(2),已知 “用户表”和 某个字段名“员工号”,那么就可以存放每一列的map对象
(3),已知 “用户表”和 某个字段名“员工号”,可以找到该列下的所有验证规则存放到map中
(4),已知 “用户表” 和 “ 员工号”和验证规则name "nullable",那么可以找到每一列的某一个验证规则
2.读取excel数据时,需要一一对应xml map中的字段与验证规则。
下面是excel数据:标注红色 * 号的表示必填项。
接下来就要看具体的实现代码了:
东西很多,我只贴两个比较重要的java 类
1.ParseExcelUtil.java ,要试验代码,可以直接在工程里面单击右键--run as 运行这个类,不过前提是要导入这个测试项目,最后面我会上传。
1. package com.karen.test2;
2.
3. import java.beans.IntrospectionException;
4. import java.io.File;
5. import java.io.FileInputStream;
6. import java.io.FileNotFoundException;
7. import java.io.IOException;
8. import java.lang.reflect.InvocationTargetException;
9. import java.util.ArrayList;
10. import java.util.HashMap;
11. import java.util.List;
12. import java.util.Map;
13.
14. import org.apache.poi.hssf.usermodel.HSSFCell;
15. import org.apache.poi.hssf.usermodel.HSSFDateUtil;
16. import org.apache.poi.hssf.usermodel.HSSFRow;
17. import org.apache.poi.hssf.usermodel.HSSFSheet;
18. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
19.
20. import com.karen.database.Dao;
21. /**
22. * 解析excel 工具类
23. * @author PCCW
24. *
25. */
26. @SuppressWarnings("rawtypes")
27. public class ParseExcelUtil {
28.
29. public FileInputStream fis ;
30. public HSSFWorkbook workBook;
31. public HSSFSheet sheet;
32. public ParseXMLUtil parseXmlUtil;
33. public StringBuffer errorString;
34.
35. /**当前实体类的code**/
36. public String curEntityCode;
37. /**表头map对象:key:entityCode, value:headMap(index,headTitle)**/
38. public Map curEntityHeadMap ;
39.
40. /**字段的必填:key:entityCode+headTitle, value:true(必填),false(不必填)**/
41. public Map curEntityColRequired;
42.
43. /**存放每一行的数据**/
44. public List listDatas ;
45.
46.
47. public ParseExcelUtil(File excelFile,File xmlFile){
48. try {
49. if(excelFile == null){
50. throw new FileNotFoundException();
51. }
52. new FileInputStream(excelFile);
53. new HSSFWorkbook(fis);
54. new ParseXMLUtil(xmlFile);
55. new StringBuffer();
56. readExcelData();
57.
58. catch (FileNotFoundException e) {
59. e.printStackTrace();
60. catch (IOException e) {
61. e.printStackTrace();
62. }
63. }
64.
65.
66. /**开始从excel读取数据**/
67. public void readExcelData(){
68. int sheetSize = workBook.getNumberOfSheets();
69. for(int i=0;i<sheetSize;i++){
70. sheet = workBook.getSheetAt(i);
71. String entityName = workBook.getSheetName(i);
72. readSheetData(sheet,entityName);
73. }
74.
75. }
76.
77. /**读每个sheet页的数据**/
78. public void readSheetData(HSSFSheet sheet,String entityName){
79.
80. int rowNumbers = sheet.getPhysicalNumberOfRows();
81. Map ent = (Map) parseXmlUtil.getEntityMap().get(entityName);
82. this.setCurEntityCode((String) ent.get("code"));
83. if(rowNumbers == 0){
84. "================excel中数据为空!");
85. errorString.append(ParseConstans.ERROR_EXCEL_NULL);
86. }
87. List colList = (List) parseXmlUtil.getColumnListMap().get(entityName);
88. int xmlRowNum = colList.size();
89. 0);
90. int excelFirstRow = excelRow.getFirstCellNum();
91. int excelLastRow = excelRow.getLastCellNum();
92. if(xmlRowNum != (excelLastRow-excelFirstRow)){
93. "==================xml列数与excel列数不相符,请检查");
94. errorString.append(ParseConstans.ERROR_EXCEL_COLUMN_NOT_EQUAL);
95. }
96. readSheetHeadData(sheet);
97.
98. readSheetColumnData(sheet,entityName);
99.
100.
101.
102. }
103.
104. /**读取sheet页中的表头信息**/
105. @SuppressWarnings({ "unchecked", "static-access"})
106. public void readSheetHeadData(HSSFSheet sheet){
107.
108. new HashMap();
109. new HashMap();
110. new HashMap();
111. 0);
112. int excelLastRow = excelheadRow.getLastCellNum();
113. "";
114. for(int i=0;i<excelLastRow;i++){
115. HSSFCell cell = excelheadRow.getCell(i);
116. this.getStringCellValue(cell).trim();
117. if(headTitle.endsWith("*")){
118. this.getCurEntityCode()+"_"+headTitle,true);
119. else{
120. this.getCurEntityCode()+"_"+headTitle,false);
121. }
122. headMap.put(i, headTitle);
123. }
124. this.getCurEntityCode(), headMap);
125. }
126.
127. /**读取sheet页里面的数据**/
128. @SuppressWarnings({ "unchecked", "static-access" })
129. public void readSheetColumnData(HSSFSheet sheet,String entityName){
130.
131. 0);
132. int excelLastcell = excelheadRow.getLastCellNum(); //excel总列数
133. int excelRowNum = sheet.getLastRowNum(); //excel总行数
134. this.getCurEntityHeadMap().get(this.getCurEntityCode());
135. Map colMap = parseXmlUtil.getColumnMap();
136. new ArrayList();
137.
138. for(int i=1;i<excelRowNum+1;i++){//行循环
139. HSSFRow columnRow = sheet.getRow(i);
140. if(columnRow != null){
141. new HashMap();
142. for(int j =0; j<excelLastcell;j++){ //列循环
143. int cout = headMap.get(j).toString().indexOf("*");
144. "";
145. if(cout == -1){
146. headTitle = headMap.get(j).toString();
147. else{
148. 0, cout);
149. }
150. "_"+headTitle);
151. "code");
152. "type");
153. HSSFCell colCell = columnRow.getCell(j);
154. this.getStringCellValue(colCell);
155. if(value != null){
156. value = value.trim();
157. }
158. "type");
159. if(xmlColType.equals("int")){
160. int intVal = Integer.valueOf(value);
161. //将这一行的数据以code-value的形式存入map
162. else{
163. curRowCellMap.put(curColCode, value);
164. }
165. /**验证cell数据**/
166. 1,j+1,colCell,entityName,headTitle,curColType);
167. }
168. listDatas.add(curRowCellMap);
169. }
170. }
171.
172. if(this.getErrorString().length() ==0){//如果没有任何错误,就保存
173. saveExcelData(entityName);
174. "导入数据成功!");
175. else{
176. //清理所有的缓存clearMap();现在暂时未清理
177. "<br>");
178. for(String s: strArr){
179. System.out.println(s);
180. }
181.
182. }
183.
184.
185. }
186. /**验证单元格数据**/
187. @SuppressWarnings("static-access")
188. public void validateCellData(int curRow,int curCol,HSSFCell colCell,String entityName,String headName,String curColType){
189.
190. "_"+headName);
191. if(rulList != null && rulList.size()>0){
192. for(int i=0 ; i<rulList.size() ; i++){
193. Map rulM = (Map) rulList.get(i);
194. "name");
195. "message");
196. this.getStringCellValue(colCell).trim();
197. if(rulName.equals(ParseConstans.RULE_NAME_NULLABLE)){
198.
199. if(cellValue.equals("")||cellValue == null){
200. "第"+curRow+"行,第"+curCol+"列:"+rulMsg+"<br>");
201. }
202. else {
203. //这里写其他的验证规则。。。
204. }
205. }
206. }
207. }
208.
209. /**保存excel里面的数据**/
210. @SuppressWarnings("unchecked")
211. public void saveExcelData(String entityName){
212.
213. new ArrayList();
214. for(int i = 0 ; i<this.getListDatas().size();i++){
215. this.getListDatas().get(i); //得到第 i 行的数据
216. new User();
217. try {
218. User obj = (User) BeanToMapUtil.convertMap(user.getClass(), excelCol);
219. users.add(obj);
220. catch (IntrospectionException e) {
221. e.printStackTrace();
222. catch (IllegalAccessException e) {
223. e.printStackTrace();
224. catch (InstantiationException e) {
225. e.printStackTrace();
226. catch (InvocationTargetException e) {
227. e.printStackTrace();
228. }
229.
230. }
231. /**批量保存数据**/
232. new Dao();
233. for(int i = 0;i<users.size();i++){
234. try{
235. dao.saveUser(users.get(i));
236.
237. catch(Exception e){
238. e.printStackTrace();
239. }
240. }
241.
242. }
243.
244. /**
245. * 获得单元格字符串
246. * @throws UnSupportedCellTypeException
247. */
248. public static String getStringCellValue(HSSFCell cell) {
249. if (cell == null){
250. return null;
251. }
252.
253. "";
254. switch (cell.getCellType()) {
255. case HSSFCell.CELL_TYPE_BOOLEAN:
256. result = String.valueOf(cell.getBooleanCellValue());
257. break;
258. case HSSFCell.CELL_TYPE_NUMERIC:
259. if (HSSFDateUtil.isCellDateFormatted(cell)) {
260. new java.text.SimpleDateFormat(
261. "yyyy-MM-dd");
262. result = TIME_FORMATTER.format(cell.getDateCellValue());
263. }
264. else{
265. double doubleValue = cell.getNumericCellValue();
266. "" + doubleValue;
267. }
268. break;
269. case HSSFCell.CELL_TYPE_STRING:
270. if (cell.getRichStringCellValue() == null){
271. null;
272. }
273. else{
274. result = cell.getRichStringCellValue().getString();
275. }
276. break;
277. case HSSFCell.CELL_TYPE_BLANK:
278. null;
279. break;
280. case HSSFCell.CELL_TYPE_FORMULA:
281. try{
282. result = String.valueOf(cell.getNumericCellValue());
283. catch(Exception e){
284. result = cell.getRichStringCellValue().getString();
285. }
286. break;
287. default:
288. "";
289. }
290.
291. return result;
292. }
293. /**主方法**/
294. public static void main(String[] args) {
295.
296. new File("src/user.xls");
297. new File("src/user.xml");
298. new ParseExcelUtil(excelFile,xmlFile);
299.
300. }
301.
302.
303.
304. public String getCurEntityCode() {
305. return curEntityCode;
306. }
307. public void setCurEntityCode(String curEntityCode) {
308. this.curEntityCode = curEntityCode;
309. }
310. public Map getCurEntityHeadMap() {
311. return curEntityHeadMap;
312. }
313. public void setCurEntityHeadMap(Map curEntityHeadMap) {
314. this.curEntityHeadMap = curEntityHeadMap;
315. }
316. public ParseXMLUtil getParseXmlUtil() {
317. return parseXmlUtil;
318. }
319. public void setParseXmlUtil(ParseXMLUtil parseXmlUtil) {
320. this.parseXmlUtil = parseXmlUtil;
321. }
322. public Map getCurEntityColRequired() {
323. return curEntityColRequired;
324. }
325. public void setCurEntityColRequired(Map curEntityColRequired) {
326. this.curEntityColRequired = curEntityColRequired;
327. }
328. public List getListDatas() {
329. return listDatas;
330. }
331. public void setListDatas(List listDatas) {
332. this.listDatas = listDatas;
333. }
334. public StringBuffer getErrorString() {
335. return errorString;
336. }
337. public void setErrorString(StringBuffer errorString) {
338. this.errorString = errorString;
339. }
340.
341.
342. }
2.ParseXMLUtil.java
这个类是用来解析xml的,测试方法同样可以右键 run as 运行。可以把下面的一段注释放开,查看打印结果。
1. package com.karen.test2;
2.
3. import java.io.File;
4. import java.io.FileInputStream;
5. import java.io.FileNotFoundException;
6. import java.util.ArrayList;
7. import java.util.HashMap;
8. import java.util.Iterator;
9. import java.util.List;
10. import java.util.Map;
11. import java.util.Set;
12.
13. import org.dom4j.Document;
14. import org.dom4j.Element;
15. import org.dom4j.io.SAXReader;
16.
17. /**
18. * 解析xml工具类
19. * @author PCCW-80352891
20. *
21. */
22. @SuppressWarnings("rawtypes")
23. public class ParseXMLUtil {
24.
25. /**entity map对象,key:name ,value:entity的属性map集**/
26. public Map entityMap ;
27.
28. /**column map 对象,key:entityName_colName , value:column的属性map集 **/
29. public Map columnMap;
30.
31. /**rule map 对象,key:entityName_colName_ruleName, value: rule 的map集:找到一行rule**/
32. public Map ruleMap ;
33.
34. /**rules map 对象, key:entityName_colName, value: rules 的map集:找到该column下所有的rule**/
35. public Map columnRulesMap ;
36.
37. /**entity--column map: key:entityName, value: column list:根据实体类名得到所有的列**/
38. public Map columnListMap ;
39.
40. /**column list**/
41. public List columnList ;
42.
43.
44. /**开始解析xml文件**/
45. public ParseXMLUtil(File xmlFilePath){
46. null;
47. try {
48. if(xmlFilePath == null){
49. throw new FileNotFoundException();
50. }
51. new SAXReader();
52. new FileInputStream(xmlFilePath);
53. Document doc = reader.read(in);
54. Element root = doc.getRootElement();
55. "entity").iterator();
56. while(itEntity.hasNext()){
57. Element entity = (Element) itEntity.next();
58. parseEntity(entity);
59. }
60.
61. /**测试entityMap 是否正确**/
62. this.getEntityMap().get("用户表");
63. Set<?> set = enMap.keySet();
64. Iterator it = set.iterator();
65. while(it.hasNext()){
66. String uu = (String) it.next();
67. "entity properties:"+uu+" = "+enMap.get(uu));
68. }
69.
70. /* *//**测试column list是否正确**//*
71. List colList = (List) this.getColumnListMap().get("用户表");
72. System.out.println("column size:"+colList.size());
73.
74. *//**测试columnMap是否正确**//*
75. Map colMap = (Map) this.getColumnMap().get("用户表_员工号");
76. Set<?> coListSet = colMap.keySet();
77. Iterator coListIt = coListSet.iterator();
78. while(coListIt.hasNext()){
79. String coListKey = (String) coListIt.next();
80. System.out.println("column properties: "+coListKey+" = "+colMap.get(coListKey));
81. }
82. *//**测试ruleMap是否正确**//*
83. if(this.getColumnRulesMap() != null){
84. List rulesValidList = (List) this.getColumnRulesMap().get("用户表_员工号");
85. for(int i=0;i<rulesValidList.size(); i++){
86. Map colRuleMap = (Map) rulesValidList.get(i);
87. String ruleName = (String) colRuleMap.get("name");
88. Map ruleMa = (Map) this.getRuleMap().get("用户表_员工号_"+ruleName); //eg: 用户表_用户名_nullable
89. String mess = (String) ruleMa.get("message");
90. System.out.println("Validate Rules"+i+" : "+mess);
91. }
92. }*/
93. catch(Exception e){
94. e.printStackTrace();
95. }
96.
97. }
98.
99. /**开始解析entity**/
100. @SuppressWarnings("unchecked")
101. public void parseEntity(Element entity){
102. if(entity != null){
103.
104. /**对数据进行初始化设置**/
105. new HashMap();
106. new HashMap();
107. new HashMap();
108. new HashMap();
109. new HashMap();
110. new ArrayList();
111.
112. setEntityMap(entity);
113. "name");
114. "column").iterator();
115. while(itColumn.hasNext()){
116. Element column = (Element) itColumn.next();
117. setColumnMap(entityName,column);
118. }
119. columnListMap.put(entityName, columnList);
120. }
121. }
122.
123.
124.
125. /**将entity放入entityMap中**/
126. @SuppressWarnings("unchecked")
127. public void setEntityMap(Element entity){
128. new HashMap();
129. "name");
130. "code");
131. "name", name);
132. "code", code);
133. entityMap.put(name, ent);
134. }
135.
136. /**将column放入columnMap中**/
137. @SuppressWarnings("unchecked")
138. public void setColumnMap(String entityName,Element column){
139. if(column != null){
140. new HashMap();
141. "name");
142. "code");
143. "type");
144. "name", name);
145. "code", code);
146. "type", type);
147. "_"+name; //eg: 用户表_用户名
148. columnMap.put(columnMapKey, col);
149. columnList.add(col);
150. "rules").iterator(); //获得rules
151. while(ruleIt.hasNext()){
152. Element rules = (Element)ruleIt.next();
153. "rule").iterator(); //获得 rule
154. while(rule.hasNext()){
155. //获得每一行rule
156. setRuleMap(entityName,name,ruleValid);
157. }
158. }
159. }
160. }
161.
162. /**将 rule 验证规则放入ruleMap中**/
163. @SuppressWarnings("unchecked")
164. public void setRuleMap(String entityName,String columnName,Element ruleValid){
165. if(ruleValid != null){
166. "name");
167. "message");
168. new HashMap();
169. "name", ruleName);
170. "message", ruleMsg);
171. "_"+columnName+"_"+ruleName;
172. "_"+columnName;
173. if(this.getColumnRulesMap().containsKey(colStrKey)){
174. this.getColumnRulesMap().get(colStrKey);
175. valids.add(ruleValidMap);
176. else{
177. new ArrayList();
178. valids.add(ruleValidMap);
179. this.columnRulesMap.put(colStrKey, valids); //将每个column下的所有rules存入该map中
180. }
181. //将每个column下的一条rule存入该map中
182. }
183. }
184.
185. /**主方法**/
186. public static void main(String[] args) {
187. new File("src/user.xml");
188. new ParseXMLUtil(file);
189. }
190.
191. /**所有的get set 方法**/
192. public Map getEntityMap() {
193. return entityMap;
194. }
195.
196. public void setEntityMap(Map entityMap) {
197. this.entityMap = entityMap;
198. }
199.
200. public Map getColumnMap() {
201. return columnMap;
202. }
203.
204. public void setColumnMap(Map columnMap) {
205. this.columnMap = columnMap;
206. }
207.
208. public Map getRuleMap() {
209. return ruleMap;
210. }
211.
212. public void setRuleMap(Map ruleMap) {
213. this.ruleMap = ruleMap;
214. }
215.
216. public Map getColumnRulesMap() {
217. return columnRulesMap;
218. }
219.
220. public void setColumnRulesMap(Map columnRulesMap) {
221. this.columnRulesMap = columnRulesMap;
222. }
223.
224. public Map getColumnListMap() {
225. return columnListMap;
226. }
227.
228. public void setColumnListMap(Map columnListMap) {
229. this.columnListMap = columnListMap;
230. }
231.
232.
233.
234. }
3.既然做导入,当然需要连接数据库啦。只需要在mysql数据库中,建立一个 名为 chat 的数据库,然后导入下面的sql.来创建一张user表
1. CREATE TABLE `user` (
2. varchar(20) default NULL,
3. int(10) NOT NULL,
4. varchar(40) NOT NULL,
5. password` varchar(10) NOT NULL,
6. varchar(100) NOT NULL,
7. no` varchar(10) default NULL,
8. `userImage` blob,
9. PRIMARY KEY (`username`)
10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4.例子肯定需要很多jar包,比如poi啊,各种包。我就不在这里写出来了。
需要例子源码 请到这里下载:
5.运行方法: 将例子导入到eclipse之中,然后可能会因为jdk版本不一样会有红色感叹号,没关系,改一下。单击项目右键--properties--java build path--libraries--找jdk啊。这个搞java的都会吧。
然后,单击右键 run as 运行ParseExcelUtil.java 就可以啦。
关于例子导入后会提示缺少包的问题:
我引入的相关jar包是在eclipse里面直接引入的,没有相对于的lib目录。主要是缺少了2个jar
poi-3.8-20120326.jar
mysql-connector-java-5.0.8-bin.jar
必须要在eclipse里引入他们。