很久沒有發文章了,前陣子一堆雜事繁瑣著。
接下來介紹的是我最近寫到EXCEL檔案上傳並要解析預覽的一個小功能。
本篇引用了以下文章內容:
首先在做這個練習前我們要確認一下使用了那些第三方套件,以及環境的確認。
jQuery & Bootstrap
有另外新增的是:
在LinqToExcel之下需要確認是否有安裝
LinqToExcel說明文件下有提到,必須安裝 Microsoft Access Database Engine 2010 Redistributable否則會造成以下錯誤:
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.'
先分享一個我在這遇到的神奇的問題,首先我在開發時採用了Visual Studio 2012 並且使用.Net FreamWrok 4.0為開發基底。
在本機端的IIS EXPRESS上執行專案的時候一切都正常。
當放到測試伺服器的時候採用IIS7.0執行的時候發生嚴重錯誤,並且IIS將應用程式集區直接自動停用,真是嚇死寶寶了。
而在製作本篇文章的時候,我採用的是Visual Studio 2017 .Net FreamWrok 4.5一直行就才有報出官方文件提到的錯誤訊息,害我當時找不到原因的時候整整傷腦筋了很久。還好最後有找到對的方向。
好啦廢話到此結束,開始我們的正文。
首先整個專案會有以下:
Controller
-HomeController -->小練習不拆架構全部塞裡面
Model
-UserList
View
-Index
-_Upload ->部分檢視
-_PreviewData->部分檢視
先從前端的HTML部分介紹起
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#UploadModal">
UpLoad
</button>
@Html.Partial("_Upload")
主畫面就長這樣一個上傳檔案的按鈕,功能就是呼叫開啟Bootstrap Moda,另外將部分參照的頁面_Upload參照近來。
<!-- UploadModal -->
<div class="modal fade" id="UploadModal" tabindex="-1" role="dialog" aria-labelledby="UploadModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="UploadModalLabel">檔案上傳</h4>
</div>
<div class="modal-body">
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput">
<i class="glyphicon glyphicon-file fileinput-exists"></i>
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">選擇檔案</span>
<span class="fileinput-exists">更換檔案</span>
<input type="file" name="file" id="file" />
</span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">移除檔案</a>
</div>
</div>
<div class="modal-footer">
<input type="button" id="ButtonCancel" class="btn btn-default" data-dismiss="modal" value="取消">
<input type="button" id="ButtonSubmit" name="ButtonSubmit" class="btn btn-primary" value="上傳檔案">
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="PreviewModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="PreviewData"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
這部分就只是放了兩個MODAL近來,比較特別的地方是<div id="PreviewData"></div>在第二個MODAL,是用來接收預覽資料用的區塊。
_PreviewData最後一個頁面放預覽資料用的程式碼如下沒什麼好介紹的。
@model IEnumerable<UploadExcelSimple.Models.UserList>
<table class="table">
<thead>
<tr>
<th>
User ID
</th>
<th>
User Name
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@item.ID
</td>
<td>
@item.Name
</td>
</tr>
}
</tbody>
</table>
接下來是重點的開始從Controller部分開始講起
這部分有分為兩個Action皆為Post才會執行的區段。
[HttpPost]
public ActionResult UpLoad()
{
var file = Request.Files as HttpFileCollectionBase;
var uploadResult = this.FileUploadHandler(file[0]);
if (uploadResult != null)
{
var DataList = ExcelPreview(uploadResult);
ViewData.Model = DataList;
}
return PartialView("_PreviewData");
}
首先檔案處理的方法在前面引用的第一篇文章中有前輩介紹到 (FileUploadHandler),不過我有稍微修改過。之後會將檔案放在GITHUB給大家參考。
接收完檔案後,透過LinqToExcel進行解析,將解析完的資料存在MODAL並回傳給_PreviewData.cshtml。
解析Excel的片段如下:
public IEnumerable<UserList> ExcelPreview(string filename)
{
var excelFile = new ExcelQueryFactory(filename); //檔案給LINQTOEXCEL函數準備解析
var targetSheetName = "";
var workSheetNames = excelFile.GetWorksheetNames(); //抓取工作表序列
foreach (var item in workSheetNames)
{
targetSheetName = item;
break;
}
var List = excelFile.Worksheet<UserList>(targetSheetName).ToList(); //將讀出的資料對應至MODAL並轉存成LIST
return List;
}
最後其實也是比較複雜一點的就是前端的接收,是透過jQuery ajax的方式進行處理。
<script>
$('#ButtonSubmit').click(function () {
var ActionUrl = '@Url.Action("Upload","Home")' //Action位置
var data = new FormData(); //宣告資料FormData型態要來存檔案資訊用的。
var files = $("#file").get(0).files;
data.append(files[0].name, files[0]);
$.ajax(
{
type: "POST",
url: ActionUrl,
contentType: false, // 告诉jQuery不要去這置Content-Type
processData: false, // 告诉jQuery不要去處理發送的數據
data: data
}).done(function (result)
{
$('#PreviewData').html(result);
$("#PreviewModal").modal()
})
});
</script>
上面有一個地方沒解釋道的就是$('#PreviewData').html(result);
這段是將ajax執行完畢後取得回來的Html碼寫入前面有說道的第二個Modal要放資料呈現的<div id="PreviewData"></div>這個部分。
以下就是整段程式跑出來的結果:
上傳檔案
預覽資料
打完收工,新手發文如有誤麻煩請用力指教,謝謝。