前言:公司有項目需要用到導入excel數據進行數據統計分析,進行對比後,發現jxls比poi少寫不少代碼,api調用也相當方便。從而在項目中採用此技術,特輯之。(闡述方式從底層到視圖層)
1、確定excel文檔中個字段的含義和文檔格式。
2、對應編寫excel相近的xml模板文件:
<?xml version="1.0" encoding="utf-8" ?>
<workbook>
//sheet名字
<worksheet name="XXXX考勤表">
<section startRow="0" endRow="0"/>
<loop startRow="1" endRow="1" items="attendanceDatas"
var="attendanceData" varType="net.xxxxtech.xxoa.vo.AttendanceData">
<section startRow="1" endRow="1">
<mapping row="1" col="0">attendanceData.number</mapping>
<mapping row="1" col="1">attendanceData.attendNum</mapping>
<mapping row="1" col="2">attendanceData.selfDefineNum</mapping>
<mapping row="1" col="3">attendanceData.name</mapping>
<mapping row="1" col="4">attendanceData.isCapacityArrange</mapping>
<mapping row="1" col="5">attendanceData.attendDate</mapping>
<mapping row="1" col="6">attendanceData.correspondingStep</mapping>
<mapping row="1" col="7">attendanceData.openTime</mapping>
<mapping row="1" col="8">attendanceData.closingTime</mapping>
<mapping row="1" col="9">attendanceData.signInTime</mapping>
<mapping row="1" col="10">attendanceData.signOutTime</mapping>
<mapping row="1" col="11">attendanceData.dueNum</mapping>
<mapping row="1" col="12">attendanceData.trueNum</mapping>
<mapping row="1" col="13">attendanceData.lateTime</mapping>
<mapping row="1" col="14">attendanceData.earlyTime</mapping>
<mapping row="1" col="15">attendanceData.isAbsent</mapping>
<mapping row="1" col="16">attendanceData.overtimeTime</mapping>
<mapping row="1" col="17">attendanceData.workTime</mapping>
<mapping row="1" col="18">attendanceData.exceptionalCase</mapping>
<mapping row="1" col="19">attendanceData.isAttend</mapping>
<mapping row="1" col="20">attendanceData.isSignOut</mapping>
<mapping row="1" col="21">attendanceData.dept</mapping>
<mapping row="1" col="22">attendanceData.usual</mapping>
<mapping row="1" col="23">attendanceData.weekend</mapping>
<mapping row="1" col="24">attendanceData.holiday</mapping>
<mapping row="1" col="25">attendanceData.attendTime</mapping>
<mapping row="1" col="26">attendanceData.usualOvertime</mapping>
<mapping row="1" col="27">attendanceData.weekendOvertime</mapping>
<mapping row="1" col="28">attendanceData.holidayOvertime</mapping>
</section>
<loopbreakcondition>
<rowcheck offset="0">
<cellcheck offset="0"></cellcheck>
</rowcheck>
</loopbreakcondition>
</loop>
</worksheet>
</workbook>
3、編寫對應的vo類:
public class AttendanceData {
private String number;//序號
private String attendNum;//考勤號碼
private String selfDefineNum;//自定義編號
private String name;//姓名
private String isCapacityArrange;//是否智能排班(true?false字段)
private String attendDate;
private String correspondingStep;//對應時段
private String openTime;//上班時間
private String closingTime;//下班時間
private String signInTime;//簽到時間
private String signOutTime;//簽退時間
private String dueNum;//應到
private String trueNum;//實到
private String lateTime;//遲到時間
private String earlyTime;//早退時間
private String isAbsent;//是否曠工
private String overtimeTime;//加班時間
private String workTime;//工作時間
private String exceptionalCase;//例外情況
private String isAttend;//應簽到
private String isSignOut;//應簽退
private String dept;//部門
private String usual;//平日
private String weekend;//週末
private String holiday;//節假日
private String attendTime;//出勤時間/工作時間
private String usualOvertime;//平日加班
private String weekendOvertime;//週末加班
private String holidayOvertime;//節假日加班
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAttendNum() {
return attendNum;
}
public void setAttendNum(String attendNum) {
this.attendNum = attendNum;
}
public String getSelfDefineNum() {
return selfDefineNum;
}
public void setSelfDefineNum(String selfDefineNum) {
this.selfDefineNum = selfDefineNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsCapacityArrange() {
return isCapacityArrange;
}
public void setIsCapacityArrange(String isCapacityArrange) {
this.isCapacityArrange = isCapacityArrange;
}
public String getAttendDate() {
return attendDate;
}
public void setAttendDate(String attendDate) {
this.attendDate = attendDate;
}
public String getCorrespondingStep() {
return correspondingStep;
}
public void setCorrespondingStep(String correspondingStep) {
this.correspondingStep = correspondingStep;
}
public String getOpenTime() {
return openTime;
}
public void setOpenTime(String openTime) {
this.openTime = openTime;
}
public String getClosingTime() {
return closingTime;
}
public void setClosingTime(String closingTime) {
this.closingTime = closingTime;
}
public String getSignInTime() {
return signInTime;
}
public void setSignInTime(String signInTime) {
this.signInTime = signInTime;
}
public String getSignOutTime() {
return signOutTime;
}
public void setSignOutTime(String signOutTime) {
this.signOutTime = signOutTime;
}
public String getDueNum() {
return dueNum;
}
public void setDueNum(String dueNum) {
this.dueNum = dueNum;
}
public String getTrueNum() {
return trueNum;
}
public void setTrueNum(String trueNum) {
this.trueNum = trueNum;
}
public String getLateTime() {
return lateTime;
}
public void setLateTime(String lateTime) {
this.lateTime = lateTime;
}
public String getEarlyTime() {
return earlyTime;
}
public void setEarlyTime(String earlyTime) {
this.earlyTime = earlyTime;
}
public String getIsAbsent() {
return isAbsent;
}
public void setIsAbsent(String isAbsent) {
this.isAbsent = isAbsent;
}
public String getOvertimeTime() {
return overtimeTime;
}
public void setOvertimeTime(String overtimeTime) {
this.overtimeTime = overtimeTime;
}
public String getWorkTime() {
return workTime;
}
public void setWorkTime(String workTime) {
this.workTime = workTime;
}
public String getExceptionalCase() {
return exceptionalCase;
}
public void setExceptionalCase(String exceptionalCase) {
this.exceptionalCase = exceptionalCase;
}
public String getIsAttend() {
return isAttend;
}
public void setIsAttend(String isAttend) {
this.isAttend = isAttend;
}
public String getIsSignOut() {
return isSignOut;
}
public void setIsSignOut(String isSignOut) {
this.isSignOut = isSignOut;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getUsual() {
return usual;
}
public void setUsual(String usual) {
this.usual = usual;
}
public String getWeekend() {
return weekend;
}
public void setWeekend(String weekend) {
this.weekend = weekend;
}
public String getHoliday() {
return holiday;
}
public void setHoliday(String holiday) {
this.holiday = holiday;
}
public String getAttendTime() {
return attendTime;
}
public void setAttendTime(String attendTime) {
this.attendTime = attendTime;
}
public String getUsualOvertime() {
return usualOvertime;
}
public void setUsualOvertime(String usualOvertime) {
this.usualOvertime = usualOvertime;
}
public String getWeekendOvertime() {
return weekendOvertime;
}
public void setWeekendOvertime(String weekendOvertime) {
this.weekendOvertime = weekendOvertime;
}
public String getHolidayOvertime() {
return holidayOvertime;
}
public void setHolidayOvertime(String holidayOvertime) {
this.holidayOvertime = holidayOvertime;
}
}
4、service類中進行數據處理(讀excel內容),其中xml模板文件寫配置:
private final static String xmlConfig = "attendanceData.xml";
@Override
public List<AttendanceData> importAttendData(String filePath) {
XLSReader mainReader;
try {
InputStream inputXML = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(xmlConfig));
mainReader = ReaderBuilder.buildFromXML(inputXML);
InputStream inputXLS = new BufferedInputStream(new FileInputStream(filePath));
List<AttendanceData> attendanceDatas = new ArrayList<>();
Map<String, Object> beans = new HashMap();
beans.put("attendanceDatas", attendanceDatas);
XLSReadStatus readStatus = mainReader.read(inputXLS, beans);
return attendanceDatas;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
}
return null;
}
5、controller類進行接口調用:
@RequestMapping(value = "importAttendData", method = RequestMethod.POST)
@ResponseBody
public ResponseResult importTestResult(MultipartFile myfile, HttpServletRequest req) throws Exception {
ResponseResult responseResult = new ResponseResult();
String templateFile = req.getSession().getServletContext().getRealPath("/import");
try {
if (myfile.isEmpty()) {
responseResult.setResult(Result.WARNING);
responseResult.setMessage("導入文件爲空!!");
return responseResult;//URLEncoder.encode("[<導入文件爲空!!>]", "UTF-8");
} else {
String fileName = myfile.getOriginalFilename();
if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx") && !fileName.endsWith(".xlsm")) {
responseResult.setResult(Result.WARNING);
responseResult.setMessage("文件類型錯誤,導入文件僅允許excel文件類型!!");
return responseResult;
}
File file = new File(templateFile);
if (!file.exists()) {
file.mkdirs();
}
FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(templateFile, myfile.getOriginalFilename()));
String resultFilePath = templateFile + File.separator + fileName;
List<AttendanceData> testReportResults = attendanceService.importAttendData(resultFilePath);
String errorInfo = "";
if (testReportResults != null) {
//i從1開始,忽略模板中的標題欄
StringBuilder stringBuilder = attendanceService.updateAttendDataByCode(testReportResults);
if (stringBuilder.length() > 0) {
String inf = stringBuilder.toString();
responseResult.setResult(Result.WARNING);
responseResult.setMessage(inf);
return responseResult;
// return java.net.URLEncoder.encode("[<" + inf + ">]", "UTF-8");
} else {
responseResult.setResult(Result.SUCCESS);
responseResult.setMessage("導入成功!!");
return responseResult;
// return "SUCCESS";//URLEncoder.encode("[<導入成功!!>]", "UTF-8");
}
} else {
responseResult.setResult(Result.FAILURE);
responseResult.setMessage("導入文件內容格式錯誤!!");
return responseResult;
// return java.net.URLEncoder.encode("[<導入文件內容格式錯誤!!>]", "UTF-8"); //URLEncoder.encode("[<導入文件內容格式錯誤!!>]", "UTF-8");
}
}
} catch (Exception e) {
e.printStackTrace();
responseResult.setResult(Result.FAILURE);
responseResult.setMessage("系統正忙,請稍後再試!!");
return responseResult;
// return java.net.URLEncoder.encode("[<系統正忙,請稍後再試!!>]", "UTF-8");
}
}
6、視圖層jsp通過ajax進行數據導入:
6.1、彈出模態框進行數據導入
<kendo:window name="reportResultWindow" title="導入考勤文檔" draggable="true" resizable="true" width="500"
height="400" visible="false">
<kendo:window-content>
<div>
<form id="submitReportResult" method="post" enctype="multipart/form-data"
style="font: 14px bold ;">
<input type="hidden" id="reportId" name="reportId"/>
<fieldset>
<legend>點擊瀏覽選擇上傳文件</legend>
<input type="file" name="myfile" style="color:red;"/>
</fieldset>
<hr/>
<fieldset>
日誌:<textarea rows="10" cols="60" id="log"
style="position: relative;right:0px;margin-top: 10px;"></textarea>
</fieldset>
註釋:
<div class="heading-buttons">
<div class="buttons pull-right" style="margin-right: 0px; margin-top: 20px;">
<input type="button" class="btn btn-primary right" value="確定"
onclick="importReportResult();"/>
</div>
</div>
</form>
</div>
</kendo:window-content>
</kendo:window>
6.2 excel文檔導入提交
function importReportResult() {
var reportId = $("#reportId").val();
if (confirm("確定導入考勤數據?")) {
$("#log").val("正在導入中...");
$("#submitReportResult").ajaxSubmit({
type: 'post',
url: "../assets/importAttendData.do",
success: function (data) {
var dataContent = JSON.stringify(decodeURI(data));
dataContent = dataContent.substring(dataContent.lastIndexOf("[<") + 2, dataContent.lastIndexOf(">]"));
var content1 = dataContent.substring(0, dataContent.lastIndexOf("!!") + 2);
var content2 = dataContent.substring(dataContent.lastIndexOf("!!") + 2, dataContent.length - 2);
if (content1 == "導入成功!!") {
$("#log").val(content1 + "\n" + content2);
$("#grid").data("kendoGrid").dataSource.read();
// $('#submit').disabled=false;
} else {
$("#log").val(dataContent);
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
$("#log").val("導入異常!");
}
});
}
}
或者
function importReportResult() {
var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串
/* if (userAgent.indexOf("Opera") > -1) {
return "Opera"
}; //判斷是否Opera瀏覽器
if (userAgent.indexOf("Firefox") > -1) {
return "FF";
} //判斷是否Firefox瀏覽器*/
var reportId = $("#reportId").val();
if (confirm("確定導入考勤數據?")) {
$("#log").val("正在導入中...");
$("#submitReportResult").ajaxSubmit({
type: 'post',
url: "../assets/importAttendData.do",
data:$(this).serialize(),
dataType:"text",
success: function (data) {
if (userAgent.indexOf("Chrome") > -1){
var reg = /<pre.+?>(.+)<\/pre>/g;
var result = data.match(reg);
data = RegExp.$1;
data = JSON.parse(data);
console.info(data.result);
}
if (data.result == "SUCCESS") {
$("#log").val("導入成功");
$("#grid").data("kendoGrid").dataSource.read();
} else {
$("#log").val(data.message);
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
$("#log").val("導入異常!");
}
});
}
}
7、後記,其實jxsl技術還可以進行很好的excel模板導出操作,後續在進行闡述。
參考文檔:
https://www.cnblogs.com/lilongsheng1125/p/4978522.html
http://blog.csdn.net/u010402228/article/details/50155771
https://www.cnblogs.com/foxlee1024/p/7616987.html