天天看點

.net core EPPlus npoi_.NetCore3.0+Angular1.x+Epplus檔案上傳,下載下傳

.net core EPPlus npoi_.NetCore3.0+Angular1.x+Epplus檔案上傳,下載下傳

最近在基于.Net Core3.0下文簡稱(Core)實踐檔案上傳,先抛出引子,再分享出我的探索經過!

http://Asp.Net Core檔案上傳IFormFile

在 Core中,檔案上傳接收類型不再使用 HttpPostedFile 或 HttpFileCollection來接收,而是使用 IFormFile 或 IFormFileCollection來接收。——

其實對于對于這種方式官方在MSDN也有簡單的例子,有興趣可以去看看! 第一階段

1.能參考的資料都是就是Razor Page,但是我的頁面是HTML(喝特抹叻),Razor Page配起asp-action,asp-Contorller簡直不要太爽;html這之後隻能過腳本輔助發起檔案上傳。

2.這個時候其實網上在這塊基于Angular1.x的參考是少至又少,對于碼農來說能copy絕對不會寫!(=.=玩笑不要當真),可能是Angular1.x的web應用現在沒有Vue在國内火,但是在全球來看Angualr1.x的Web應用是Vue不能比,這個時候我又要懷念一下google...

總結:這個階段就是看完還是不知怎麼着手,參考資料少! 第二個階段 我看了在基于Core這塊的資料在資料上出現2路分歧,第一路NPOI,第二路EPPlus,分别看了一下最後決定用EPPlus,原因

NPOI導出Excel和EPPlus導出Excel比較

看完這位大佬的分享,因為我直接是基于Core3.0的是以使用的EPPlus,EPPlus.core已被棄用(Core2.2版本)。

NPIO官網位址:http://npoi.codeplex.com/

EPPlus官網位址:http://epplus.codeplex.com/

影響較深參考資料:net core 上傳并使用EPPlus導入Excel檔案 向前輩敬禮!

Angular1.x + Core3.0 +EPPlus 實踐篇
你有你的Razor Page的文法糖一氣呵成,爽的起飛,我有我的$http,雖然繞點路但是還是可以實作目的! 實作原則原生FromData

FormData對象用以将資料編譯成鍵值對,以便用

XMLHttpRequest

來發送資料。其主要用于發送表單資料,但亦可用于發送帶鍵資料(keyed data),而獨立于表單使用。如果表單

enctype

屬性設為multipart/form-data ,則會使用表單的

submit()

方法來發送資料,進而,發送資料具有同樣形式。 ——引用FormData 對象的使用

HTML(喝特抹叻)核心代碼
<form method="post" id="uploadForm" enctype="multipart/form-data">
        <div class="modal-content" style="height: 100%;width: 450px;margin-top: 20px;">
            <table class="table table-borderless" style="width:100%">
                <tr>
                    <td>上傳</td>
                </tr>
                <tr>
                    <td><input type="file" name="file" multiple/></td>
                </tr>
            </table>

            <div style="margin-top:30px;margin-bottom:10px;margin-left:150px">
                <button type="button" class="btn btn-success" style="margin-right:5px" data-dismiss="none" ng-click="doUpload()" id="btu-Ses">導入</button>
                <button type="button" class="btn btn-light" data-dismiss="modal">傳回</button>
            </div>
        </div>
    </form>
           

HTML代碼注意事項無,平淡無奇!

Angular1.x——$http
$scope.doUpload = function () {
                        var formData = new FormData($("#uploadForm")[0]);
                        $http({
                            method: 'POST',
                            url: ProxyService + '/uploadfiles',
                            data: formData,
                            headers: { 'Content-Type': undefined },
                            transformRequest: angular.identity 
                        }).then(function (response) {
                            console.log(response);
                        });
                    }
           

注意事項:防止采坑

重識$http

:隻要涉及到與背景進行資料互動,我們可以使用内置的$http服務直接同外部進行通信。$http服務隻是簡單的封裝了浏覽器原生的XMLHttpRequest對象。

将$http當做函數來使用,這時需要傳入一個設定對象,用來說明如何構造XHR對象。
$http({
method:'GET',
url:'/api/xxxx',
params:{
'name':'huitai'
});
 
其中設定對象可以包含以下主要的鍵:
Method
可以是:GET/DELETE/HEAD/JSONP/POST/PUT
URL:絕對的或者相對的請求目标
params:字元串或者對象
這個鍵的值是一個字元串或對象,會被轉換成查詢字元串追加在URL後面。如果值不是字元串,會被JSON序列化。
比如這個:
//參數會轉為?age=18的形式
$http({
params:{'age':18}
});
④data(字元串或者對象)
這個對象中包含了将會被當作消息體發送給伺服器的資料。通常在發送POST請求時使用。

從AngularJS 1.3開始,它還可以在POST請求裡發送二進制資料。要發送一個blob對象,你可以簡單地通過使用data參數來傳遞它。
後端接收不到AngularJS $http.POST異步背景無法擷取請求參數解決方法就會報415/500之類的錯誤,如下圖!

           
.net core EPPlus npoi_.NetCore3.0+Angular1.x+Epplus檔案上傳,下載下傳

其實大家都知道其中Angular的post和put都是application/json,AngularJS1.x傳輸資料使用Content-Type: application/json和{ "name": "huitai", "age": "8" }這樣的json序列。是以把Content-Type設定成x-www-form-urlencodedand之後,還需要轉換序列的格式傳輸的資料不然必然報錯!

.net core EPPlus npoi_.NetCore3.0+Angular1.x+Epplus檔案上傳,下載下傳
總結重識$http
1.HTTP請求的content-Type字段指明了送出的資料格式,而原生HTML的資料格式是x-www-form-urlencode 2.服務端默會以x-www-form-urlencode的方式去解析POST的參數,不認識就會報錯.

剛才叙說我是想用FromData實作上傳其最主要的原因是

:FormData的最大優點就是我們可以異步上傳一個二進制檔案.
重要普及
Anjular1.x的$http請求來上傳檔案的,是以要讓目前的request成為一個Multipart/form-data請求,Anjular1.x對于POST和GET請求預設的Content-Type header 是application/json。通過設定‘Content-Type’: undefined,這樣浏覽器不僅幫我們把Content-Type 設定為 multipart/form-data,還填充上目前的boundary,如果你手動設定為:'Content-Type': multipart/form-data,背景會抛出異常:the current request boundary parameter is null。通過設定 transformRequest: angular.identity ,Anjular transformRequest function 将序列化我們的formdata object. 簡單總結:
  1. Content-Type:undefined,然後工作交給浏覽器
  2. transformRequest: angular.identity
Core3.0 EPPlus

Controller:

[HttpPost("uploadfiles")]
        public async Task<IActionResult> UploadFiles()
        {
            .....
            var files = Request.Form.Files;
            if (files == null || files.Sum(f => f.Length) == 0)
            {
                return Ok(new CommonViewData { ErrorStr = "檔案無效", IsSucceed = false });
            }
            else
            {
                foreach (var x in files)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                       await x.CopyToAsync(memoryStream).ConfigureAwait(false);
                        using (var package = new ExcelPackage(memoryStream))
                        {
                            var worksheet = package.Workbook.Worksheets[0]; //擷取工作簿
                            ICollection<StuEPPlus> ePPlus = StuEPPlusTool.Import(package, worksheet);
                            #region 插入邏輯部分
                            .....
                            #endregion
                        }
                    }
                }
            }
            return Ok(new CommonViewData { ErrorStr = "上傳成功", IsSucceed = true });
        }
           

EPPlus簡單實用:

public static ICollection<T> Import(ExcelPackage package, ExcelWorksheet worksheet)
        {
            ICollection<T> ePPlus = new List<T>();

            var rowCount = worksheet.Dimension?.Rows;
            var colCount = worksheet.Dimension?.Columns;
            #region 檢查文檔格式
            if (!rowCount.HasValue || !colCount.HasValue)
            {
                return ePPlus;
                //return "文檔表頭或内容為空,請下載下傳對應文檔!";
            }
            if (!worksheet.Cells[3, 1].Value.Equals("Name") ||
                !worksheet.Cells[3, 2].Value.Equals("NickeName") ||
                !worksheet.Cells[3, 3].Value.Equals("Tel") ||
                !worksheet.Cells[3, 4].Value.Equals("Address") ||
                !worksheet.Cells[3, 5].Value.Equals("E-Mail"))
            {
                return ePPlus;
                //return "文檔表頭或内容不對應,請下載下傳對應文檔!";
            }
            #endregion
            #region  讀取資料
            for (int i = 4; i <= rowCount; i++)
            {
                 //i=幾 取決模版開始行數
                ePPlus.Add(new t
                {
                    Name = worksheet.Cells[i, 1].Value.ToString(),
                    NickeName= worksheet.Cells[i, 2].Value.ToString(),
                    Tel= worksheet.Cells[i, 3].Value.ToString(),
                    Address= worksheet.Cells[i, 4].Value.ToString(),
                    E-Mail= worksheet.Cells[i, 5].Value.ToString()
                });
            }
            #endregion
            return ePPlus;
        }
           

至此一個簡單.NetCore3.0+Angular1.x+Epplus檔案上傳就完成了,下載下傳則更為簡單後續等我上傳換上angular-file-upload元件後補~~~