天天看点

.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组件后补~~~