Monday, 1 May 2017

File upload in Angularjs

Introduction

File upload is a common feature of many applications. Sometimes we need to upload multiple files with some data.

Problem StatementI have developedan application using AngularJS and Web API 2 and I want to upload files as well as post some data. Both data and files, I want to post in a single request. How to achieve this?

SolutionThis can be done in many ways. Here I am discussing one way that I feel is the best. The following steps are required tobe performed to achieve this. In this way, I will use directive in AngularJS and Web API.

Step 1: Define AngularJS Application.
  1. var app = angular.module("AngularApp", []);  
Step 2: Define “uploadFiles” directive 
Here, I have created a simple directive for file upload that picks up the selected files and emits "selectedFiles" event which is written in Angular controller. In this event we just add files which are selected in to the files array. Later on in this article we will look this into controller code and will discuss it.
  1. app.directive('uploadFiles', function () {  
  2.     return {  
  3.         scope: true,        //create a new scope  
  4.         link: function (scope, el, attrs) {  
  5.             el.bind('change', function (event) {  
  6.                 var files = event.target.files;  
  7.                 //iterate files since 'multiple' may be specified on the element  
  8.                 for (var i = 0; i < files.length; i++) {  
  9.                     //emit event upward  
  10.                     scope.$emit("seletedFile", { file: files[i] });  
  11.                 }  
  12.             });  
  13.         }  
  14.     };  
  15. });  
Step 3: Define angular ControllerNext step is to define the angular controller. In the controller, I have defined “selectedFile” event which is emitted from the directive. In this event we just push the selected files in to array. Later on this will used to post the files. I have also defined dummy JSON data which I want to post to Web API with selected files. Save method of the controller is use angular http service to post data and files. The transformRequest is http service property and it can be a single function that returns the transformed value. Here we just are overriding the default Transformations. This will allow us to change way of data send up to the server.
  1. app.controller("demoController", function ($scope, $http) {  
  2.     //1. Used to list all selected files  
  3.     $scope.files = [];  
  4.   
  5.     //2. a simple model that want to pass to Web API along with selected files  
  6.     $scope.jsonData = {  
  7.         name: "Jignesh Trivedi",  
  8.         comments: "Multiple upload files"  
  9.     };  
  10.     //3. listen for the file selected event which is raised from directive  
  11.     $scope.$on("seletedFile", function (event, args) {  
  12.         $scope.$apply(function () {  
  13.             //add the file object to the scope's files collection  
  14.             $scope.files.push(args.file);  
  15.         });  
  16.     });  
  17.   
  18.     //4. Post data and selected files.  
  19.     $scope.save = function () {  
  20.         $http({  
  21.             method: 'POST',  
  22.             url: "http://localhost:51739/PostFileWithData",  
  23.             headers: { 'Content-Type': undefined },  
  24.              
  25.             transformRequest: function (data) {  
  26.                 var formData = new FormData();  
  27.                 formData.append("model", angular.toJson(data.model));  
  28.                 for (var i = 0; i < data.files.length; i++) {  
  29.                     formData.append("file" + i, data.files[i]);  
  30.                 }  
  31.                 return formData;  
  32.             },  
  33.             data: { model: $scope.jsonData, files: $scope.files }  
  34.         }).  
  35.         success(function (data, status, headers, config) {  
  36.             alert("success!");  
  37.         }).  
  38.         error(function (data, status, headers, config) {  
  39.             alert("failed!");  
  40.         });  
  41.     };  
  42. });  
Step 4: HTML MarkupNext step is to define the markup. 
  1. <!DOCTYPE html>  
  2. <html data-ng-app="AngularApp">  
  3. <head>  
  4.     <meta content="IE=edge, chrome=1" http-equiv="X-UA-Compatible" />  
  5.     <title>AngularJS - Example</title>  
  6.     <script src="Script\angular.js"></script>  
  7.     <script src="Script\app.js"></script>  
  8.     <script src="Script\demoController.js"></script>  
  9.     <script src="Script\fileUploadDirective.js"></script>  
  10.   
  11. </head>  
  12. <body>  
  13.     <div ng-controller="demoController">  
  14.         <b>Post JSON data and files in Same Request with AngularJS and Web API example</b>  
  15.         <br />  
  16.         <br />  
  17.         <input type="file" upload-files multiple />  
  18.         <ul>  
  19.             <li ng-repeat="file in files">{{file.name}}</li>  
  20.         </ul>  
  21.         <br />  
  22.         <br />  
  23.         <button ng-click="save()">Save</button>  
  24.     </div>  
  25. </body>  
  26. </html>  
Step 5: Web API ControllerIn this step, I have created Web API controller with standard way. In following highlight code, we get the our posted JSON data as well as posted iles.
  1. public class MyDataController : ApiController  
  2. {  
  3.     [HttpPost]  
  4.     [Route("PostFileWithData")]  
  5.     public async Task<HttpResponseMessage> Post()  
  6.     {  
  7.         if (!Request.Content.IsMimeMultipartContent())  
  8.         {  
  9.             throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);  
  10.         }  
  11.   
  12.         var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploadfiles");  
  13.         Directory.CreateDirectory(root);  
  14.         var provider = new MultipartFormDataStreamProvider(root);  
  15.         var result = await Request.Content.ReadAsMultipartAsync(provider);  
  16.              
  17.   
  18.         var model = result.FormData["jsonData"];  
  19.         if (model == null)  
  20.         {  
  21.             throw new HttpResponseException(HttpStatusCode.BadRequest);  
  22.         }  
  23.         //TODO: Do something with the JSON data.  
  24.          
  25.         //get the posted files  
  26.         foreach (var file in result.FileData)  
  27.         {  
  28.             //TODO: Do something with uploaded file.  
  29.         }  
  30.   
  31.         return Request.CreateResponse(HttpStatusCode.OK, "success!");  
  32.     }  
  33. }  



 var file = Request.Files[0];
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/File/"), fileName);
            file.SaveAs(path);
            Application oExcel = new Application(); 
            string filepath = path;  
            Workbook WB = oExcel.Workbooks.Open(filepath);
            string ExcelWorkbookname = WB.Name;
            List<string> listMT = new List<string>();
            foreach (Worksheet obj in WB.Worksheets)
                if(obj.Name.Substring(0,2)=="MT")
                listMT.Add(obj.Name.Substring(3));
            Worksheet wks = (Worksheet)WB.Worksheets[1];
           int rows= wks.Rows.Count;
         int cols=   wks.Columns.Count;
            string firstworksheetname = wks.Name;
            var firstcellvalue = ((Range)wks.Cells[1, 1]).Value;
            return Json(listMT, JsonRequestBehavior.AllowGet);


----------------------------------------------------------------------------------------------

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}


<div class="container">
    <form class="form-horizontal" enctype="multipart/form-data">
        <fieldset>
            <legend>From</legend>
            <div class="form-group">
                <label class="control-label col-lg-4">RCN/ACN Excel File Upload</label>
                <div class="col-lg-4">
                    <input type="file" id="Upload" value="Upload" class="form-control" />
                    <span id="errorMessage" style="color:red"></span>
                </div>
                <div class="col-lg-4">
                    <input type="button" id="btnUpload" value="Upload" class="btn btn-primary" style="width:80px" />
                </div>
            </div>
        </fieldset>
       
        <fieldset class="fields">
            <legend>For</legend>
            <div class="form-group">
                <label class="control-label col-lg-4">Product</label>
                <div class="col-lg-4">
                   <span class="cbGroup"></span>
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-lg-4"></label>
                <div class="col-lg-4">
                    <input type="button" class="btn bg-primary" value="Convert Into XML" />
                </div>
            </div>
        </fieldset>
     
          </form>
</div>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
    $(function () {
       
        $('#Upload').change(function () {
            if ($('#Upload').val() == "") {
                $('#errorMessage').text('Please select a file');
                return false;
            }
            else {
                $('#errorMessage').text('');
            }
        }); $('.fields').hide();
        $('#btnUpload').click(function () {
            if ($('#Upload').val() == "") {
                $('#errorMessage').text('Please select a file');
                return false;
            }
            else {
                $('#errorMessage').text('');
            }
            var formData = new FormData();
            var file = document.getElementById("Upload").files[0];
            formData.append("rcexcel", file);
            
            $.ajax({
                type: "POST",
                url: '/RCTOXML/Fetchexcelfile',
                data: formData,
                dataType: 'json',
                contentType: false,
                processData: false,
                success: function (data) {
                    $('.fields').show();
                    $.each(data, function (i, j) {
                        $('.cbGroup').append("<input type='checkbox' class='cb' />  " + j + "<br>");
                    });
                },
                error: function (error) {
                    alert("errror");
                }
            });
        });
    });

</script>
-----------------------------------------------------------------------------------------------
controller

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WDOne.Models;
using Microsoft.Office.Interop.Excel;


namespace WDOne.Controllers
{
    public class RCTOXMLController : Controller
    {
        // GET: RCTOXML
        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public JsonResult Fetchexcelfile()
        {

            try
            {
                var file = Request.Files[0];
                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/RCExcelFile/"), fileName);
                if (!System.IO.File.Exists(path))
                {
                    file.SaveAs(path);
                }
                int index = 0, Tr = 0, Pv = 0, Fopv = 0;
                string cvalue = string.Empty;
                Range objRange = null;
                Application app = new Application();
                Workbook WB = app.Workbooks.Open(path);
                List<string> listMT = new List<string>();
                foreach (Worksheet obj in WB.Worksheets)
                {
                    

                        if (obj.Name.Substring(0, 2) == "MT")
                        {
                            for (index = 1; index < obj.Columns.Count; index++)
                            {
                                objRange = obj.Cells[1, index];
                                cvalue = objRange.Text;
                                string[] tvalue = cvalue.Split('\n');
                                cvalue = tvalue[0].Trim() + " " + tvalue[1].Trim();
                                if (cvalue.Trim() == "Table Revison".Trim())
                                    Tr = index;
                                if (cvalue.Trim() == "Parameter Version".Trim())
                                    Pv = index;
                                if (cvalue.Trim() == "Final Outgoing Parameter Version".Trim())
                                {
                                    Fopv = index;
                                    break;
                                }
                            }
                            listMT.Add("Table revision : " + ((Range)obj.Cells[3, Tr]).Text + "  Incoming version : " + ((Range)obj.Cells[3, Pv]).Text + "  Outgoing version : " + ((Range)obj.Cells[3, Fopv]).Text);
                        }

                    
                    
                }
                return Json(listMT, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(ex.Message, JsonRequestBehavior.AllowGet);
            }


        }
    }

}

No comments:

Post a Comment