今天來講下企業(yè)的開發(fā)的一些功能應(yīng)用吧,就是Ajax使用,以及簡單的企業(yè)報(bào)表的導(dǎo)入導(dǎo)出,基于原有的項(xiàng)目進(jìn)行展示(其實(shí)是本博主想偷懶)。
本系列:
(一)項(xiàng)目框架整合構(gòu)建
(二)建立商品數(shù)據(jù)庫和Lucene的搭建
(三) Redis系列(一)--安裝、helloworld以及讀懂配置文件
(四)Redis系列(二)--緩存設(shè)計(jì)(整表緩存以及排行榜緩存方案實(shí)現(xiàn))
(五) Lucene總結(jié)系列(一)--認(rèn)識(shí)、helloworld以及基本的api操作。
(六)Lucene總結(jié)系列(二)--商品檢索系統(tǒng)的文字檢索業(yè)務(wù)(lucene項(xiàng)目使用)
(七)Lucene總結(jié)系列(三)--總述優(yōu)化方案和呈現(xiàn)實(shí)時(shí)內(nèi)存索引實(shí)現(xiàn)(結(jié)合RAMDirectory源碼解析)
(八)JavaWeb--Servlet過濾器Filter和SpringMVC的HandlerInterceptor(Session和Cookie登錄認(rèn)證)
(九)Redis系列(三)--過期策略
(十)Redis系列(四)--內(nèi)存淘汰機(jī)制(含單機(jī)版內(nèi)存優(yōu)化建議)
文章結(jié)構(gòu):(1)Ajax使用詳解(級(jí)聯(lián)列表例子);(2)企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出;
一、Ajax使用詳解(級(jí)聯(lián)列表例子):
(1)概述:
AJAX 不是新的編程語言,而是一種使用現(xiàn)有標(biāo)準(zhǔn)的新方法。
AJAX 最大的優(yōu)點(diǎn)是在不重新加載整個(gè)頁面的情況下,可以與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁內(nèi)容。
AJAX 不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執(zhí)行。
應(yīng)用:
運(yùn)用XHTML+CSS來表達(dá)資訊;
運(yùn)用JavaScript操作DOM(Document Object Model)來執(zhí)行動(dòng)態(tài)效果;
運(yùn)用XML和XSLT操作資料;
運(yùn)用XMLHttpRequest或新的Fetch API與網(wǎng)頁服務(wù)器進(jìn)行異步資料交換;
注意:AJAX與Flash、Silverlight和Java Applet等RIA技術(shù)是有區(qū)分的。
不適用:
部分簡單的表單
搜索
基本的導(dǎo)航
替換大量的文本
.對(duì)呈現(xiàn)的操縱
缺點(diǎn):轉(zhuǎn)載自此
1. AJAX干掉了Back和History功能,即對(duì)瀏覽器機(jī)制的破壞。在動(dòng)態(tài)更新頁面的情況下,用戶無法回到前一個(gè)頁面狀態(tài),因?yàn)闉g覽器僅能記憶歷史記錄中的靜態(tài)頁面。
2. AJAX的安全問題。
AJAX技術(shù)給用戶帶來很好的用戶體驗(yàn)的同時(shí)也對(duì)IT企業(yè)帶來了新的安全威脅,Ajax技術(shù)就如同對(duì)企業(yè)數(shù)據(jù)建立了一個(gè)直接通道。這使得開發(fā)者在不經(jīng)意間會(huì)暴露比以前更多的數(shù)據(jù)和服務(wù)器邏輯。Ajax的邏輯可以對(duì)客戶端的安全掃描技術(shù)隱藏起來,允許黑客從遠(yuǎn)端服務(wù)器上建立新的攻擊。還有Ajax也難以避免一些已知的安全弱點(diǎn),諸如跨站點(diǎn)腳步攻擊、SQL注入攻擊和基于Credentials的安全漏洞等等。
3. 對(duì)搜索引擎支持較弱:
對(duì)搜索引擎的支持比較弱。如果使用不當(dāng),AJAX會(huì)增大網(wǎng)絡(luò)數(shù)據(jù)的流量,從而降低整個(gè)系統(tǒng)的性能。
4. 違背URL和資源定位的初衷。
例如,我給你一個(gè)URL地址,如果采用了Ajax技術(shù),也許你在該URL地址下面看到的和我在這個(gè)URL地址下看到的內(nèi)容是不同的。這個(gè)和資源定位的初衷是相背離的。
5. 客戶端過肥,太多客戶端代碼造成開發(fā)上的成本。
編寫復(fù)雜、容易出錯(cuò) ;冗余代碼比較多(層層包含js文件是AJAX的通病,再加上以往的很多服務(wù)端代碼現(xiàn)在放到了客戶端);破壞了Web的原有標(biāo)準(zhǔn)。
簡單描述工作原理:
Ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了—個(gè)中間層(AJAX引擎),使用戶操作與服務(wù)器響應(yīng)異步化。并不是所有的用戶請(qǐng)求都提交給服務(wù)器,像—些數(shù)據(jù)驗(yàn)證和數(shù)據(jù)處理等都交給Ajax引擎自己來做, 只有確定需要從服務(wù)器讀取新數(shù)據(jù)時(shí)再由Ajax引擎代為向服務(wù)器提交請(qǐng)求。
Ajax其核心有JavaScript、XMLHTTPRequest、DOM對(duì)象組成,通過XmlHttpRequest對(duì)象來向服務(wù)器發(fā)異步請(qǐng)求,從服務(wù)器獲得數(shù)據(jù),然后用JavaScript來操作DOM而更新頁面。這其中最關(guān)鍵的一步就是從服務(wù)器獲得請(qǐng)求數(shù)據(jù)。讓我們來了解這幾個(gè)對(duì)象。
最基本的例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<div id="myDiv"><h2> AJAX HelloWorld</h2></div>
<button type="button" onclick="loadXMLDoc()">修改內(nèi)容</button>
</script>
</head>
<body>
<script>
function loadXMLDoc(){
//在里面去使用ajax做請(qǐng)求,以及更新前端UI
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執(zhí)行代碼
xmlhttp=new XMLHttpRequest();
}
else{
// IE6, IE5 瀏覽器執(zhí)行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
xmlhttp.send();
}
</script>
下面是我們今天要做的全部功能啦。
這里寫圖片描述
(2)級(jí)聯(lián)表實(shí)現(xiàn):
描述:
就是在不更新頁面情況下:商品地址,會(huì)更新下面所說的對(duì)應(yīng)賬號(hào)(博主為了偷懶,簡單寫的邏輯)。
圖片展示:
這里寫圖片描述
這里寫圖片描述
功能展示:選擇廣東省或北京市后:賬號(hào)自動(dòng)更新
這里寫圖片描述
實(shí)現(xiàn):demo代碼
(一)前端代碼:
//注意我給select添加了一個(gè)監(jiān)聽喔。
<div class="modal">
<p>
<label>商品地址:</label>
<select name="location" id="location" onchange="locationChange()">
<option value="">請(qǐng)選擇</option>
<option value="廣東省">廣東省</option>
<option value="北京市">北京市</option>
</select>
</p>
<p>
<label>列出對(duì)應(yīng)的賬號(hào):</label>
<select name="accounts" id="accounts">
<option value="">請(qǐng)選擇</option>
</select>
</p>
</div>
(2)方法監(jiān)聽就看方法嘛:方法體詳解在后面(下面的例子注釋使用時(shí)請(qǐng)刪去)
//$.ajax里面就是ajax的方法啦,動(dòng)態(tài)加載:
<script>
function locationChange() {
var location = $("#location").find("option:selected").text();
alert(location)
var obj = document.getElementById('accounts');//綁定select
obj.options.length = 0;
obj.add(new Option("請(qǐng)選擇", ""));
$.ajax({
type: "post", //請(qǐng)求類型
url: "/ajax/findUserByProvince", //請(qǐng)求路徑
cache: false, //緩存是否啟用
data: {location: location}, //傳參
dataType: "json", //期望返回的數(shù)據(jù)體
success: function (result) {
//result是后臺(tái)返回給前端的結(jié)果集,而我們上面期望他是一個(gè)json,所以就是個(gè)json數(shù)組咯
if (result.length > 0) {
obj.add(new Option("請(qǐng)選擇", ""));
for (var i in result) {//遍歷取值更新select
var selectOption = new Option(result[i].account, result[i].account);
obj.add(selectOption);
}
}
}
});
}
</script>
(3)接下來看后端的處理:
@ResponseBody
@RequestMapping(value = "/findUserByProvince",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String findUserByProvince(String location){
List<User> userList = userService.findUserByProvince(location);//這個(gè)只是一個(gè)簡單的根據(jù)省份去查詢用戶賬號(hào)的邏輯,想了解細(xì)節(jié)下方有源碼下載
System.out.println(JSON.toJSONString(userList));
//返回一個(gè)json數(shù)組給前端
return JSON.toJSONString(userList);
}
補(bǔ)充:有朋友反應(yīng)下面這個(gè)jQuery使用看不太懂
//$("#location")是綁定了id是location的標(biāo)簽組件
//find("option:selected")是拿到上面的標(biāo)簽組件下面的option
//使用text()就是可以拿到內(nèi)容啦。
var location = $("#location").find("option:selected").text();
這就是一個(gè)簡單的級(jí)聯(lián)列表實(shí)現(xiàn),結(jié)合ajax。
(3)下面就詳細(xì)講解ajax方法體的各大參數(shù)吧:以下部分轉(zhuǎn)載此博主此博客
(一)url:
要求為String類型的參數(shù),(默認(rèn)為當(dāng)前頁地址)發(fā)送請(qǐng)求的地址。
(二)type:
要求為String類型的參數(shù),請(qǐng)求方式(post或get)默認(rèn)為get。注意其他http請(qǐng)求方法,例如put和delete也可以使用,但僅部分瀏覽器支持。
(三)timeout:
要求為Number類型的參數(shù),設(shè)置請(qǐng)求超時(shí)時(shí)間(毫秒)。此設(shè)置將覆蓋$.ajaxSetup()方法的全局設(shè)置。
(四)async:
要求為Boolean類型的參數(shù),默認(rèn)設(shè)置為true,所有請(qǐng)求均為異步請(qǐng)求。如果需要發(fā)送同步請(qǐng)求,請(qǐng)將此選項(xiàng)設(shè)置為false。注意,同步請(qǐng)求將鎖住瀏覽器,用戶其他操作必須等待請(qǐng)求完成才可以執(zhí)行。
(五)cache
要求為Boolean類型的參數(shù),默認(rèn)為true(當(dāng)dataType為script時(shí),默認(rèn)為false),設(shè)置為false將不會(huì)從瀏覽器緩存中加載請(qǐng)求信息。
(六)data:
要求為Object或String類型的參數(shù),發(fā)送到服務(wù)器的數(shù)據(jù)。如果已經(jīng)不是字符串,將自動(dòng)轉(zhuǎn)換為字符串格式。get請(qǐng)求中將附加在url后。防止這種自動(dòng)轉(zhuǎn)換,可以查看 processData選項(xiàng)。對(duì)象必須為key/value格式,例如{foo1:"bar1",foo2:"bar2"}轉(zhuǎn)換為&foo1=bar1&foo2=bar2。如果是數(shù)組,JQuery將自動(dòng)為不同值對(duì)應(yīng)同一個(gè)名稱。例如{foo:["bar1","bar2"]}轉(zhuǎn)換為&foo=bar1&foo=bar2。
(七)dataType:
要求為String類型的參數(shù),預(yù)期服務(wù)器返回的數(shù)據(jù)類型。如果不指定,JQuery將自動(dòng)根據(jù)http包mime信息返回responseXML或responseText,并作為回調(diào)函數(shù)參數(shù)傳遞??捎玫念愋腿缦拢?/h4>
xml:返回XML文檔,可用JQuery處理。
html:返回純文本HTML信息;包含的script標(biāo)簽會(huì)在插入DOM時(shí)執(zhí)行。
script:返回純文本JavaScript代碼。不會(huì)自動(dòng)緩存結(jié)果。除非設(shè)置了cache參數(shù)。注意在遠(yuǎn)程請(qǐng)求時(shí)(不在同一個(gè)域下),所有post請(qǐng)求都將轉(zhuǎn)為get請(qǐng)求。
json:返回JSON數(shù)據(jù)。
jsonp:JSONP格式。使用SONP形式調(diào)用函數(shù)時(shí),例如myurl?callback=?,JQuery將自動(dòng)替換后一個(gè)“?”為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù)。
text:返回純文本字符串。
(八)beforeSend:
要求為Function類型的參數(shù),發(fā)送請(qǐng)求前可以修改XMLHttpRequest對(duì)象的函數(shù),例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次ajax請(qǐng)求。XMLHttpRequest對(duì)象是惟一的參數(shù)。
function(XMLHttpRequest){
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
(九)complete:
要求為Function類型的參數(shù),請(qǐng)求完成后調(diào)用的回調(diào)函數(shù)(請(qǐng)求成功或失敗時(shí)均調(diào)用)。參數(shù):XMLHttpRequest對(duì)象和一個(gè)描述成功請(qǐng)求類型的字符串。
function(XMLHttpRequest, textStatus){
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
(十)success:
要求為Function類型的參數(shù),請(qǐng)求成功后調(diào)用的回調(diào)函數(shù),有兩個(gè)參數(shù)。
(1)由服務(wù)器返回,并根據(jù)dataType參數(shù)進(jìn)行處理后的數(shù)據(jù)。
(2)描述狀態(tài)的字符串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
(十一)error:
要求為Function類型的參數(shù),請(qǐng)求失敗時(shí)被調(diào)用的函數(shù)。該函數(shù)有3個(gè)參數(shù),即XMLHttpRequest對(duì)象、錯(cuò)誤信息、捕獲的錯(cuò)誤對(duì)象(可選)。ajax事件函數(shù)如下:
function(XMLHttpRequest, textStatus, errorThrown){
//通常情況下textStatus和errorThrown只有其中一個(gè)包含信息
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
(十二)contentType:
要求為String類型的參數(shù),當(dāng)發(fā)送信息至服務(wù)器時(shí),內(nèi)容編碼類型默認(rèn)為"application/x-www-form-urlencoded"。該默認(rèn)值適合大多數(shù)應(yīng)用場合。
(十三)dataFilter:
要求為Function類型的參數(shù),給Ajax返回的原始數(shù)據(jù)進(jìn)行預(yù)處理的函數(shù)。提供data和type兩個(gè)參數(shù)。data是Ajax返回的原始數(shù)據(jù),type是調(diào)用jQuery.ajax時(shí)提供的dataType參數(shù)。函數(shù)返回的值將由jQuery進(jìn)一步處理。
function(data, type){
//返回處理后的數(shù)據(jù)
return data;
}
(十四)global:
要求為Boolean類型的參數(shù),默認(rèn)為true。表示是否觸發(fā)全局ajax事件。設(shè)置為false將不會(huì)觸發(fā)全局ajax事件,ajaxStart或ajaxStop可用于控制各種ajax事件。
(十五)ifModified:
要求為Boolean類型的參數(shù),默認(rèn)為false。僅在服務(wù)器數(shù)據(jù)改變時(shí)獲取新數(shù)據(jù)。服務(wù)器數(shù)據(jù)改變判斷的依據(jù)是Last-Modified頭信息。默認(rèn)值是false,即忽略頭信息。
(十六)jsonp:
要求為String類型的參數(shù),在一個(gè)jsonp請(qǐng)求中重寫回調(diào)函數(shù)的名字。該值用來替代在"callback=?"這種GET或POST請(qǐng)求中URL參數(shù)里的"callback"部分,例如{jsonp:'onJsonPLoad'}會(huì)導(dǎo)致將"onJsonPLoad=?"傳給服務(wù)器。
(十七)username:
要求為String類型的參數(shù),用于響應(yīng)HTTP訪問認(rèn)證請(qǐng)求的用戶名。
(十八)password:
要求為String類型的參數(shù),用于響應(yīng)HTTP訪問認(rèn)證請(qǐng)求的密碼。
(十九)processData:
要求為Boolean類型的參數(shù),默認(rèn)為true。默認(rèn)情況下,發(fā)送的數(shù)據(jù)將被轉(zhuǎn)換為對(duì)象(從技術(shù)角度來講并非字符串)以配合默認(rèn)內(nèi)容類型"application/x-www-form-urlencoded"。如果要發(fā)送DOM樹信息或者其他不希望轉(zhuǎn)換的信息,請(qǐng)?jiān)O(shè)置為false。
(二十)scriptCharset:
要求為String類型的參數(shù),只有當(dāng)請(qǐng)求時(shí)dataType為"jsonp"或者"script",并且type是GET時(shí)才會(huì)用于強(qiáng)制修改字符集(charset)。通常在本地和遠(yuǎn)程的內(nèi)容編碼不同時(shí)使用。
(二十一)$.each()函數(shù):
$.each()函數(shù)不同于JQuery對(duì)象的each()方法,它是一個(gè)全局函數(shù),不操作JQuery對(duì)象,而是以一個(gè)數(shù)組或者對(duì)象作為第1個(gè)參數(shù),以一個(gè)回調(diào)函數(shù)作為第2個(gè)參數(shù)?;卣{(diào)函數(shù)擁有兩個(gè)參數(shù):第1個(gè)為對(duì)象的成員或數(shù)組的索引,第2個(gè)為對(duì)應(yīng)變量或內(nèi)容。
(4)涉及的重要對(duì)象:
(一)XMLHTTPRequest對(duì)象:(Ajax獨(dú)有)
Ajax的一個(gè)最大的特點(diǎn)是無需刷新頁面便可向服務(wù)器傳輸或讀寫數(shù)據(jù)(又稱無刷新更新頁面),這一特點(diǎn)主要得益于XMLHTTP組件XMLHTTPRequest對(duì)象。
function(XMLHttpRequest){
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
function(XMLHttpRequest, textStatus){
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
function(XMLHttpRequest, textStatus, errorThrown){
//通常情況下textStatus和errorThrown只有其中一個(gè)包含信息
this; //調(diào)用本次ajax請(qǐng)求時(shí)傳遞的options參數(shù)
}
function(data, type){
//返回處理后的數(shù)據(jù)
return data;
}
| 方 法 | 描述 |
|---|---|
| abort() | 停止當(dāng)前請(qǐng)求 |
| getAllResponseHeaders() | 把HTTP請(qǐng)求的所有響應(yīng)首部作為鍵/值對(duì)返回 |
| getResponseHeader("header") | 返回指定首部的串值 |
| open("method","URL",[asyncFlag],["userName"],["password"]) | 建立對(duì)服務(wù)器的調(diào)用。method參數(shù)可以是GET、POST或PUT。url參數(shù)可以是相對(duì)URL或絕對(duì)URL。這個(gè)方法還包括3個(gè)可選的參數(shù),是否異步,用戶名,密碼 |
| send(content) | 向服務(wù)器發(fā)送請(qǐng)求 |
| setRequestHeader("header", "value") | 把指定首部設(shè)置為所提供的值。在設(shè)置任何首部之前必須先調(diào)用open()。設(shè)置header并和請(qǐng)求一起發(fā)送 ('post'方法一定要 ) |
| ----- | ---- |
XMLHttpRequest 對(duì)象屬性描述
| 屬 性 | 描 述 |
|---|---|
| onreadystatechange | 狀態(tài)改變的事件觸發(fā)器,每個(gè)狀態(tài)改變時(shí)都會(huì)觸發(fā)這個(gè)事件處理器,通常會(huì)調(diào)用一個(gè)JavaScript函數(shù) |
| readyState | 請(qǐng)求的狀態(tài)。有5個(gè)可取值:0 = 未初始化,1 = 正在加載,2 = 已加載,3 = 交互中,4 = 完成 |
| responseText | 服務(wù)器的響應(yīng),返回?cái)?shù)據(jù)的文本。 |
| responseXML | 服務(wù)器的響應(yīng),返回?cái)?shù)據(jù)的兼容DOM的XML文檔對(duì)象 ,這個(gè)對(duì)象可以解析為一個(gè)DOM對(duì)象。 |
| responseBody | 服務(wù)器返回的主題(非文本格式) |
| responseStream | 服務(wù)器返回的數(shù)據(jù)流 |
| status | 服務(wù)器的HTTP狀態(tài)碼(如:404 = "文件末找到" 、200 ="成功" ,等等) |
| statusText | 服務(wù)器返回的狀態(tài)文本信息 ,HTTP狀態(tài)碼的相應(yīng)文本(OK或Not Found(未找到)等等) |
(二)DOM Document Object Model
DOM是給HTML和XML文件使用的一組API。它提供了文件的結(jié)構(gòu)表述,讓你可以改變其中的內(nèi)容及可見物。其本質(zhì)是建立網(wǎng)頁與Script或程序語言溝通的橋梁。所有WEB開發(fā)人員可操作及建立文件的屬性、方法及事件都以對(duì)象來展現(xiàn)(例如,document就代表“文件本身“這個(gè)對(duì)像,table對(duì)象則代表HTML的表格對(duì)象等等)。這些對(duì)象可以由當(dāng)今大多數(shù)的瀏覽器以Script來取用。一個(gè)用HTML或XHTML構(gòu)建的網(wǎng)頁也可以看作是一組結(jié)構(gòu)化的數(shù)據(jù),這些數(shù)據(jù)被封在DOM(Document Object Model)中,DOM提供了網(wǎng)頁中各個(gè)對(duì)象的讀寫的支持。
二、企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出:
(1)Excel報(bào)表導(dǎo)出:
實(shí)現(xiàn):
(一)MAVEN對(duì)應(yīng)的庫先:POI、還有文件上傳的包:
<!--文件上傳-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<!-- POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
(二)制作Excel樣式:
創(chuàng)建個(gè)Excel文件,定義自己喜歡的顏色字體,,,就這么簡單:
這里寫圖片描述
然后:另存為xls格式或者xlsx格式
這里寫圖片描述
(三)打開那個(gè)滿是xml代碼的文件復(fù)制到我們的jsp中
這里寫圖片描述
到j(luò)sp文件中:doExcel.jsp
至于數(shù)據(jù)如何接入??看下注釋吧。而且!??!我們只需要在兩部分寫入數(shù)據(jù)解析代碼,其余不要?jiǎng)樱?/h4>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*"%>
<%@ page import="com.fuzhu.entity.GoodDetails" %>
<%
//首先看到我們上面導(dǎo)入的java包。然后在這里拿到后臺(tái)傳過來的list
String titleName = "商品列表";
response.addHeader("Content-disposition", "attachment;filename=" + (new String(titleName.getBytes("GBK"), "iso-8859-1")) + ".xls");
//拿到數(shù)據(jù)
List<String> headList=(List)request.getAttribute("headList");
List<GoodDetails> dataList=(List)request.getAttribute("resultList");
%>
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Created>2006-09-13T11:21:51Z</Created>
<LastSaved>2011-10-20T11:56:16Z</LastSaved>
<Version>12.00</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<RemovePersonalInformation/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>11640</WindowHeight>
<WindowWidth>19200</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>90</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Center"/>
<Borders/>
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="11" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s66" ss:Name="常規(guī) 2 2 2">
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="12"/>
</Style>
<Style ss:ID="s62">
<Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
</Style>
<Style ss:ID="s67" ss:Parent="s66">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
</Borders>
<Font ss:FontName="宋體" x:CharSet="134" ss:Color="#FFFFFF" ss:Bold="1"/>
<Interior ss:Color="#0066CC" ss:Pattern="Solid"/>
</Style>
<Style ss:ID="s68">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
</Borders>
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="9"/>
<Interior ss:Color="#C0C0C0" ss:Pattern="Solid"/>
</Style>
</Styles>
<!-- 文件名字-->
<Worksheet ss:Name="商品列表">
<Table ss:ExpandedColumnCount="<%=headList.size() %>" ss:ExpandedRowCount="65000" x:FullColumns="1"
x:FullRows="1" ss:DefaultColumnWidth="99" ss:DefaultRowHeight="20.0625">
<Row ss:AutoFitHeight="0" ss:Height="33.75">
<%
//看到Row沒有,就是行的意思,我們要自建循環(huán)去遍歷我們拿到的數(shù)據(jù)。我們先遍歷頭部(頂欄一般有說明的嘛),然后再去遍歷數(shù)據(jù)欄
for(int i=0;i<headList.size();i++){
%>
<Cell ss:StyleID="s67"><Data ss:Type="String"><%=headList.get(i) %></Data></Cell>
<%
}
%>
</Row>
<%
//遍歷數(shù)據(jù)欄
for(int x=0;x<dataList.size();x++){
%>
<Row ss:AutoFitHeight="0">
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodName()==null?"":dataList.get(x).getGoodName()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodBrand()==null?"":dataList.get(x).getGoodBrand()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getStoreAdd()==null?"":dataList.get(x).getStoreAdd()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getSellerCredit()==null?"":dataList.get(x).getSellerCredit()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodPrice()==null?"":dataList.get(x).getGoodPrice()%></Data></Cell>
</Row>
<%
}
%>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<Unsynced/>
<Print>
<ValidPrinterInfo/>
<PaperSizeIndex>9</PaperSizeIndex>
<HorizontalResolution>200</HorizontalResolution>
<VerticalResolution>200</VerticalResolution>
</Print>
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>1</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
(四)傳給用戶的Excel文件寫完了,我們要怎樣在后臺(tái)交接數(shù)據(jù)呢??
@RequestMapping(value = "/getExcel",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String getExcel(HttpServletRequest request){
String location ="";
List<GoodDetails> goodlist = goodService.getGoodList(location);//查出數(shù)據(jù)
request.setAttribute("resultList",goodlist);
List<String> headList = new ArrayList<>();//頂欄的list
headList.add("商品名");
headList.add("商品類型");
headList.add("商品地址");
headList.add("商品星級(jí)");
headList.add("商品價(jià)格");
request.setAttribute("headList",headList);
return "doExcel";
}
這是前端點(diǎn)擊的下載按鈕。
這里寫圖片描述
<div style="width:100%;text-align:center">
<button><a href="getExcel">下載商品列表</a></button>
</div>
(2)Excel報(bào)表導(dǎo)入:
(一)給出我們的規(guī)范:讓用戶下載(博主順手做多了兩份模板,就給大家用啦,哈哈,見下方源碼)
這里寫圖片描述
(二)留出我們的導(dǎo)入接口:
前端:
<div>
<form id="formItem" method="post" action="uploadExcel" enctype="multipart/form-data">
<div id="fileArea"
style="text-align: left; margin: 10px 10px 10px 20px;">
<p>
<label>選擇導(dǎo)入文件:</label>
<input type="file" id="filename" name="filename" />
</p>
<input type="button" name="upload" id="upload" value="導(dǎo)入數(shù)據(jù)" onclick="doLoadTask()">
</div>
</form>
</div>
<div id="manualHelpTable"
style="text-align: left; margin-left: 20px;">
<table>
<tbody style="vertical-align: top;">
<tr>
<td style="white-space:nowrap;">文件類型:</td>
<td>
.xls或.xlsx電子表格文件 (1.表格中不需要留空行; 2.文件名的后綴必須是小寫的".xls"或".xlsx";)
</td>
</tr>
<tr>
<td style="white-space:nowrap;">備注:</td>
<td>
<pre>導(dǎo)入支持新增,暫不支持修改數(shù)據(jù),僅支持商品數(shù)據(jù)導(dǎo)入</pre>
</td>
</tr>
<tr>
<td style="white-space:nowrap;">導(dǎo)入模板:</td>
<td style="color: blue;">
<a href="../../source/plan.xls">商品表導(dǎo)入模板.xls</a>
<a href="../../source/plan.xls">商品表導(dǎo)入模板.xlsx</a>
</td>
</tr>
</tbody>
</table>
</div>
(三)利用js寫好上傳函數(shù)--檢查文件表層規(guī)范(后綴、大小等等)、導(dǎo)入步驟:
function doLoadTask() {
var file = $("#filename").val();
if (file == '') {
alert("請(qǐng)選擇待處理文件");
return;
} else {
//獲取文件類型后綴
var temp = file.substring(file.lastIndexOf("\\") + 1).toString();
// alert(temp)
var extend = file.substring(file.lastIndexOf(".") + 1).toString();
// alert(extend)
if (extend == "") {
alert("請(qǐng)選擇正確格式的文件!");
return;
} else {
if (!(extend == "xlsx") && !(extend == "xls")) {
alert("請(qǐng)選擇正確格式的文件!");
return;
}
}
}
// var form = document.getElementById("formItem");
$("#formItem").submit();
}
(四)后端接收用戶上傳的文件:controller層
@Autowired
private ParseExcel parseExcel;
@RequestMapping(value = "/uploadExcel",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String uploadExcel(HttpServletRequest request ,@RequestParam(value = "filename", required = false) MultipartFile file){
String path = request.getSession().getServletContext().getRealPath("uploadExcel");
String fileName = file.getOriginalFilename();//拿到文件名
System.out.println(path);
File targetFile = new File(path, fileName);//存儲(chǔ)的目錄名
System.out.println(targetFile);
System.out.println(targetFile.toString());
if(!targetFile.exists()){
targetFile.mkdirs();//不存在目錄就創(chuàng)建咯
}
//保存
try {
file.transferTo(targetFile);
} catch (Exception e) {
e.printStackTrace();
}
List<GoodDetails> list = null;//拿到我們導(dǎo)入的list后就是往數(shù)據(jù)庫批量插入了,這個(gè)就太簡單了,我就不寫了。
if(fileName.endsWith(".xls")||fileName.endsWith(".xlsx")) {
list = parseExcel.parseExcel((File) targetFile, targetFile.toString());
}
return "success";
}
(五)接收的文件后,想要導(dǎo)入到數(shù)據(jù)庫的前提還有一對(duì)一的數(shù)據(jù)檢驗(yàn)以及數(shù)據(jù)獲取,然后才可用對(duì)象存儲(chǔ)方式寫入數(shù)據(jù)庫
//定義解析接口
public interface ParseExcel {
List<GoodDetails> parseExcel(File xlsFile,String filename);
}
一對(duì)一的數(shù)據(jù)獲取與校驗(yàn)
@Service
public class ParseExcelImpl implements ParseExcel {
@Override
public List<GoodDetails> parseExcel(File xlsFile, String filename) {
boolean isE2007 = false; //判斷是否是excel2007格式
if (filename.endsWith("xlsx"))
isE2007 = true;
System.out.println(isE2007);
List<GoodDetails> goodDetailsList = new ArrayList<>();
try {
InputStream input = new FileInputStream(filename); //建立輸入流
Workbook wb = null;
//根據(jù)文件格式(2003或者2007)來初始化
if (isE2007)
wb = new XSSFWorkbook(input);//xlsx后綴
else
wb = new HSSFWorkbook(input);//xls后綴
System.out.println(wb);
Sheet sheet = wb.getSheetAt(0); //獲得第一個(gè)表單
Iterator<Row> rows = sheet.rowIterator(); //獲得第一個(gè)表單的迭代器
while (rows.hasNext()) {//遍歷每一行
Row row = rows.next(); //獲得行數(shù)據(jù)
System.out.println("Row #" + row.getRowNum()); //獲得行號(hào)從0開始
Iterator<Cell> cells = row.cellIterator(); //獲得第一行的迭代器
GoodDetails goodDetails = null;
if (row.getRowNum() > 0) {
goodDetails = new GoodDetails(); //每行一條記錄嘛
System.out.println("第幾行 " + row.getRowNum());
}
while (cells.hasNext()) {//在每一行基礎(chǔ)上去遍歷每一列
Cell cell = cells.next();//指向下一列
int i = cell.getColumnIndex();//拿到列的標(biāo)記
System.out.println("Cell #" + cell.getColumnIndex());
if (goodDetails != null) {
switch (i) {//針對(duì)列去獲取解析,放進(jìn)我們的java對(duì)象
case 0:
goodDetails.setGoodName(String.valueOf(cell.getStringCellValue()));
break;
case 1:
goodDetails.setGoodBrand(String.valueOf(cell.getStringCellValue()));
break;
case 2:
goodDetails.setStoreAdd(String.valueOf(cell.getStringCellValue()));
break;
case 3:
goodDetails.setSellerCredit(String.valueOf(cell.getStringCellValue()));
break;
case 4:
goodDetails.setGoodPrice(String.valueOf(cell.getNumericCellValue()));
break;
default:
System.out.println("unsuported sell type");
break;
}
}
//下面這段注釋代碼,給大家認(rèn)識(shí)下每一列對(duì)應(yīng)的數(shù)據(jù)類型:
// switch (cell.getCellType()) { //根據(jù)cell中的類型來輸出數(shù)據(jù)
// case HSSFCell.CELL_TYPE_NUMERIC: //讀取數(shù)字
// //先看是否是日期格式
// if(HSSFDateUtil.isCellDateFormatted(cell)){
// //讀取日期格式
// System.out.print("一 "+cell.getDateCellValue()+" ");
// }else{
// //讀取數(shù)字
// System.out.print("一 "+cell.getNumericCellValue()+" ");
// if (goodDetails!=null){
// goodDetails.setGoodPrice(String.valueOf(cell.getNumericCellValue()));
// }
//
// }
// break;
// case HSSFCell.CELL_TYPE_STRING://讀取文本對(duì)象
// System.out.println("二 "+cell.getStringCellValue());
//
// break;
// case HSSFCell.CELL_TYPE_BOOLEAN: //得到Boolean對(duì)象的方法
// System.out.println("三 "+cell.getBooleanCellValue());
// break;
// case HSSFCell.CELL_TYPE_FORMULA://得到公式
// System.out.println("四 "+cell.getCellFormula());
// break;
// default:
// System.out.println("unsuported sell type");
// break;
// }
}
goodDetailsList.add(goodDetails);//拿到我們導(dǎo)入的list后就是往數(shù)據(jù)庫批量插入了,這個(gè)就太簡單了,我就不寫了。
}
System.out.println(goodDetailsList.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return goodDetailsList;
}
}
然后??下載文件,對(duì)著格式輸入,然后上傳
這里寫圖片描述
## 源碼下載:[J2EE項(xiàng)目系列(四)--SSM框架構(gòu)建積分系統(tǒng)和基本商品檢索系統(tǒng)(Spring+SpringMVC+MyBatis)(3)Ajax使用詳解(級(jí)聯(lián)列表)以及企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出實(shí)現(xiàn)](https://github.com/FuZhucheng/SSM)
### 好了,J2EE項(xiàng)目系列(四)--SSM框架構(gòu)建積分系統(tǒng)和基本商品檢索系統(tǒng)(Spring+SpringMVC+MyBatis)(3)Ajax使用詳解(級(jí)聯(lián)列表)以及企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出實(shí)現(xiàn)講完了,這是實(shí)習(xí)時(shí)候所學(xué)到的一些功能點(diǎn),在這里寫出來記錄,這是積累的必經(jīng)一步,我會(huì)繼續(xù)出這個(gè)系列文章,分享經(jīng)驗(yàn)給大家。歡迎在下面指出錯(cuò)誤,共同學(xué)習(xí)??!你的點(diǎn)贊是對(duì)我最好的支持!!
### 更多內(nèi)容,可以訪問[JackFrost的博客](http://blog.csdn.net/jack__frost?viewmode=contents)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*"%>
<%@ page import="com.fuzhu.entity.GoodDetails" %>
<%
//首先看到我們上面導(dǎo)入的java包。然后在這里拿到后臺(tái)傳過來的list
String titleName = "商品列表";
response.addHeader("Content-disposition", "attachment;filename=" + (new String(titleName.getBytes("GBK"), "iso-8859-1")) + ".xls");
//拿到數(shù)據(jù)
List<String> headList=(List)request.getAttribute("headList");
List<GoodDetails> dataList=(List)request.getAttribute("resultList");
%>
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Created>2006-09-13T11:21:51Z</Created>
<LastSaved>2011-10-20T11:56:16Z</LastSaved>
<Version>12.00</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<RemovePersonalInformation/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>11640</WindowHeight>
<WindowWidth>19200</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>90</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Center"/>
<Borders/>
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="11" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s66" ss:Name="常規(guī) 2 2 2">
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="12"/>
</Style>
<Style ss:ID="s62">
<Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
</Style>
<Style ss:ID="s67" ss:Parent="s66">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
</Borders>
<Font ss:FontName="宋體" x:CharSet="134" ss:Color="#FFFFFF" ss:Bold="1"/>
<Interior ss:Color="#0066CC" ss:Pattern="Solid"/>
</Style>
<Style ss:ID="s68">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"
ss:Color="#000000"/>
</Borders>
<Font ss:FontName="宋體" x:CharSet="134" ss:Size="9"/>
<Interior ss:Color="#C0C0C0" ss:Pattern="Solid"/>
</Style>
</Styles>
<!-- 文件名字-->
<Worksheet ss:Name="商品列表">
<Table ss:ExpandedColumnCount="<%=headList.size() %>" ss:ExpandedRowCount="65000" x:FullColumns="1"
x:FullRows="1" ss:DefaultColumnWidth="99" ss:DefaultRowHeight="20.0625">
<Row ss:AutoFitHeight="0" ss:Height="33.75">
<%
//看到Row沒有,就是行的意思,我們要自建循環(huán)去遍歷我們拿到的數(shù)據(jù)。我們先遍歷頭部(頂欄一般有說明的嘛),然后再去遍歷數(shù)據(jù)欄
for(int i=0;i<headList.size();i++){
%>
<Cell ss:StyleID="s67"><Data ss:Type="String"><%=headList.get(i) %></Data></Cell>
<%
}
%>
</Row>
<%
//遍歷數(shù)據(jù)欄
for(int x=0;x<dataList.size();x++){
%>
<Row ss:AutoFitHeight="0">
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodName()==null?"":dataList.get(x).getGoodName()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodBrand()==null?"":dataList.get(x).getGoodBrand()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getStoreAdd()==null?"":dataList.get(x).getStoreAdd()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getSellerCredit()==null?"":dataList.get(x).getSellerCredit()%></Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String"><%=dataList.get(x).getGoodPrice()==null?"":dataList.get(x).getGoodPrice()%></Data></Cell>
</Row>
<%
}
%>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<Unsynced/>
<Print>
<ValidPrinterInfo/>
<PaperSizeIndex>9</PaperSizeIndex>
<HorizontalResolution>200</HorizontalResolution>
<VerticalResolution>200</VerticalResolution>
</Print>
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>1</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
@RequestMapping(value = "/getExcel",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String getExcel(HttpServletRequest request){
String location ="";
List<GoodDetails> goodlist = goodService.getGoodList(location);//查出數(shù)據(jù)
request.setAttribute("resultList",goodlist);
List<String> headList = new ArrayList<>();//頂欄的list
headList.add("商品名");
headList.add("商品類型");
headList.add("商品地址");
headList.add("商品星級(jí)");
headList.add("商品價(jià)格");
request.setAttribute("headList",headList);
return "doExcel";
}
這里寫圖片描述
<div style="width:100%;text-align:center">
<button><a href="getExcel">下載商品列表</a></button>
</div>
這里寫圖片描述
<div>
<form id="formItem" method="post" action="uploadExcel" enctype="multipart/form-data">
<div id="fileArea"
style="text-align: left; margin: 10px 10px 10px 20px;">
<p>
<label>選擇導(dǎo)入文件:</label>
<input type="file" id="filename" name="filename" />
</p>
<input type="button" name="upload" id="upload" value="導(dǎo)入數(shù)據(jù)" onclick="doLoadTask()">
</div>
</form>
</div>
<div id="manualHelpTable"
style="text-align: left; margin-left: 20px;">
<table>
<tbody style="vertical-align: top;">
<tr>
<td style="white-space:nowrap;">文件類型:</td>
<td>
.xls或.xlsx電子表格文件 (1.表格中不需要留空行; 2.文件名的后綴必須是小寫的".xls"或".xlsx";)
</td>
</tr>
<tr>
<td style="white-space:nowrap;">備注:</td>
<td>
<pre>導(dǎo)入支持新增,暫不支持修改數(shù)據(jù),僅支持商品數(shù)據(jù)導(dǎo)入</pre>
</td>
</tr>
<tr>
<td style="white-space:nowrap;">導(dǎo)入模板:</td>
<td style="color: blue;">
<a href="../../source/plan.xls">商品表導(dǎo)入模板.xls</a>
<a href="../../source/plan.xls">商品表導(dǎo)入模板.xlsx</a>
</td>
</tr>
</tbody>
</table>
</div>
function doLoadTask() {
var file = $("#filename").val();
if (file == '') {
alert("請(qǐng)選擇待處理文件");
return;
} else {
//獲取文件類型后綴
var temp = file.substring(file.lastIndexOf("\\") + 1).toString();
// alert(temp)
var extend = file.substring(file.lastIndexOf(".") + 1).toString();
// alert(extend)
if (extend == "") {
alert("請(qǐng)選擇正確格式的文件!");
return;
} else {
if (!(extend == "xlsx") && !(extend == "xls")) {
alert("請(qǐng)選擇正確格式的文件!");
return;
}
}
}
// var form = document.getElementById("formItem");
$("#formItem").submit();
}
@Autowired
private ParseExcel parseExcel;
@RequestMapping(value = "/uploadExcel",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String uploadExcel(HttpServletRequest request ,@RequestParam(value = "filename", required = false) MultipartFile file){
String path = request.getSession().getServletContext().getRealPath("uploadExcel");
String fileName = file.getOriginalFilename();//拿到文件名
System.out.println(path);
File targetFile = new File(path, fileName);//存儲(chǔ)的目錄名
System.out.println(targetFile);
System.out.println(targetFile.toString());
if(!targetFile.exists()){
targetFile.mkdirs();//不存在目錄就創(chuàng)建咯
}
//保存
try {
file.transferTo(targetFile);
} catch (Exception e) {
e.printStackTrace();
}
List<GoodDetails> list = null;//拿到我們導(dǎo)入的list后就是往數(shù)據(jù)庫批量插入了,這個(gè)就太簡單了,我就不寫了。
if(fileName.endsWith(".xls")||fileName.endsWith(".xlsx")) {
list = parseExcel.parseExcel((File) targetFile, targetFile.toString());
}
return "success";
}
//定義解析接口
public interface ParseExcel {
List<GoodDetails> parseExcel(File xlsFile,String filename);
}
@Service
public class ParseExcelImpl implements ParseExcel {
@Override
public List<GoodDetails> parseExcel(File xlsFile, String filename) {
boolean isE2007 = false; //判斷是否是excel2007格式
if (filename.endsWith("xlsx"))
isE2007 = true;
System.out.println(isE2007);
List<GoodDetails> goodDetailsList = new ArrayList<>();
try {
InputStream input = new FileInputStream(filename); //建立輸入流
Workbook wb = null;
//根據(jù)文件格式(2003或者2007)來初始化
if (isE2007)
wb = new XSSFWorkbook(input);//xlsx后綴
else
wb = new HSSFWorkbook(input);//xls后綴
System.out.println(wb);
Sheet sheet = wb.getSheetAt(0); //獲得第一個(gè)表單
Iterator<Row> rows = sheet.rowIterator(); //獲得第一個(gè)表單的迭代器
while (rows.hasNext()) {//遍歷每一行
Row row = rows.next(); //獲得行數(shù)據(jù)
System.out.println("Row #" + row.getRowNum()); //獲得行號(hào)從0開始
Iterator<Cell> cells = row.cellIterator(); //獲得第一行的迭代器
GoodDetails goodDetails = null;
if (row.getRowNum() > 0) {
goodDetails = new GoodDetails(); //每行一條記錄嘛
System.out.println("第幾行 " + row.getRowNum());
}
while (cells.hasNext()) {//在每一行基礎(chǔ)上去遍歷每一列
Cell cell = cells.next();//指向下一列
int i = cell.getColumnIndex();//拿到列的標(biāo)記
System.out.println("Cell #" + cell.getColumnIndex());
if (goodDetails != null) {
switch (i) {//針對(duì)列去獲取解析,放進(jìn)我們的java對(duì)象
case 0:
goodDetails.setGoodName(String.valueOf(cell.getStringCellValue()));
break;
case 1:
goodDetails.setGoodBrand(String.valueOf(cell.getStringCellValue()));
break;
case 2:
goodDetails.setStoreAdd(String.valueOf(cell.getStringCellValue()));
break;
case 3:
goodDetails.setSellerCredit(String.valueOf(cell.getStringCellValue()));
break;
case 4:
goodDetails.setGoodPrice(String.valueOf(cell.getNumericCellValue()));
break;
default:
System.out.println("unsuported sell type");
break;
}
}
//下面這段注釋代碼,給大家認(rèn)識(shí)下每一列對(duì)應(yīng)的數(shù)據(jù)類型:
// switch (cell.getCellType()) { //根據(jù)cell中的類型來輸出數(shù)據(jù)
// case HSSFCell.CELL_TYPE_NUMERIC: //讀取數(shù)字
// //先看是否是日期格式
// if(HSSFDateUtil.isCellDateFormatted(cell)){
// //讀取日期格式
// System.out.print("一 "+cell.getDateCellValue()+" ");
// }else{
// //讀取數(shù)字
// System.out.print("一 "+cell.getNumericCellValue()+" ");
// if (goodDetails!=null){
// goodDetails.setGoodPrice(String.valueOf(cell.getNumericCellValue()));
// }
//
// }
// break;
// case HSSFCell.CELL_TYPE_STRING://讀取文本對(duì)象
// System.out.println("二 "+cell.getStringCellValue());
//
// break;
// case HSSFCell.CELL_TYPE_BOOLEAN: //得到Boolean對(duì)象的方法
// System.out.println("三 "+cell.getBooleanCellValue());
// break;
// case HSSFCell.CELL_TYPE_FORMULA://得到公式
// System.out.println("四 "+cell.getCellFormula());
// break;
// default:
// System.out.println("unsuported sell type");
// break;
// }
}
goodDetailsList.add(goodDetails);//拿到我們導(dǎo)入的list后就是往數(shù)據(jù)庫批量插入了,這個(gè)就太簡單了,我就不寫了。
}
System.out.println(goodDetailsList.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return goodDetailsList;
}
}
這里寫圖片描述
## 源碼下載:[J2EE項(xiàng)目系列(四)--SSM框架構(gòu)建積分系統(tǒng)和基本商品檢索系統(tǒng)(Spring+SpringMVC+MyBatis)(3)Ajax使用詳解(級(jí)聯(lián)列表)以及企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出實(shí)現(xiàn)](https://github.com/FuZhucheng/SSM)
### 好了,J2EE項(xiàng)目系列(四)--SSM框架構(gòu)建積分系統(tǒng)和基本商品檢索系統(tǒng)(Spring+SpringMVC+MyBatis)(3)Ajax使用詳解(級(jí)聯(lián)列表)以及企業(yè)級(jí)報(bào)表Excel導(dǎo)入導(dǎo)出實(shí)現(xiàn)講完了,這是實(shí)習(xí)時(shí)候所學(xué)到的一些功能點(diǎn),在這里寫出來記錄,這是積累的必經(jīng)一步,我會(huì)繼續(xù)出這個(gè)系列文章,分享經(jīng)驗(yàn)給大家。歡迎在下面指出錯(cuò)誤,共同學(xué)習(xí)??!你的點(diǎn)贊是對(duì)我最好的支持!!
### 更多內(nèi)容,可以訪問[JackFrost的博客](http://blog.csdn.net/jack__frost?viewmode=contents)