NPOI при импорте excel — возвращает пользовательский интерфейс внутри пользовательского интерфейса вместо таблицы в пользовательском интерфейсе

#c# #asp.net #excel #asp.net-core #npoi

#c# #asp.net #excel #asp.net-core #npoi

Вопрос:

Мне нужно создать представление в ASP.NET Core , которое принимает Excel в качестве входных данных в виде загрузки файла и отображает таблицу содержимого файла Excel в пользовательском интерфейсе.

Я следил за этим блогом, чтобы попытаться использовать библиотеку NPOI для выполнения моей цели.

Мое представление называется XYZ/Index.cshtml так:

 <form method="post" enctype="multipart/form-data">
    <div class="form-group form-inline" id="uploadFileForm">
        <label id="lblUsersCsvFile">Choose File to Upload:</label> amp;nbsp;
        <input type="file" class="form-control" name="files" id="fUpload"> amp;nbsp;
        <label id="lblChooseContainer">Choose Container:</label> amp;nbsp;
        <select class="form-control" id="dropdownContainerOfCsv">
            <option> -- select an option -- </option>
            <option> Group Container </option>
            <option> Application Container </option>
        </select>

    </div>

    <div class="form-group">
        <div class="col-md-10">
            <input type="button" id="btnPreviewCsv" value="Preview" />
        </div>
    </div>

    <br />

    <div id="dvData"></div>

</form>


@section Scripts
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('#btnPreviewCsv').on('click', function () {
                var fileExtension = ['xls', 'xlsx'];
                var filename = $('#fUpload').val();

                if (filename.length == 0) {
                    alert("Please select a file.");
                    return false;
                }
                else {
                    var extension = filename.replace(/^.*./, '');
                    if ($.inArray(extension, fileExtension) == -1) {
                        alert("Please select only excel files with extension .xls or .xlsx.");
                        return false;
                    }
                }
                var fdata = new FormData();
                var fileUpload = $("#fUpload").get(0);
                var files = fileUpload.files;
                fdata.append(files[0].name, files[0]);
                $.ajax({
                    type: "POST",
                    url: "/XYZ?handler=Import",
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("XSRF-TOKEN",
                            $('input:hidden[name="__RequestVerificationToken"]').val());
                    },
                    data: fdata,
                    contentType: false,
                    processData: false,
                    success: function (response) {
                        if (response.length == 0)
                            alert('Some error occured while uploading');
                        else {
                            $('#dvData').html(response);
                        }
                    },
                    error: function (e) {
                        $('#dvData').html(e.responseText);
                    }
                });
            })
        });
    </script>
}

  

и мой связанный контроллер называется XYZController is:

 public class XYZController : Controller
    {
        private IHostingEnvironment _hostingEnvironment;
        public XYZController(IHostingEnvironment hostingEnvironment)
        {
            _hostingEnvironment = hostingEnvironment;
        }

        public IActionResult Index()
        {
            return View();
        }

        public ActionResult OnPostImport()
        {
            IFormFile file = Request.Form.Files[0];
            string folderName = "Upload";
            string webRootPath = _hostingEnvironment.WebRootPath;
            string newPath = Path.Combine(webRootPath, folderName);
            StringBuilder sb = new StringBuilder();
            if (!Directory.Exists(newPath))
            {
                Directory.CreateDirectory(newPath);
            }
            if (file.Length > 0)
            {
                string sFileExtension = Path.GetExtension(file.FileName).ToLower();
                ISheet sheet;
                string fullPath = Path.Combine(newPath, file.FileName);
                using (var stream = new FileStream(fullPath, FileMode.Create))
                {
                    file.CopyTo(stream);
                    stream.Position = 0;
                    if (sFileExtension == ".xls")
                    {
                        HSSFWorkbook hssfwb = new HSSFWorkbook(stream); //This will read the Excel 97-2000 formats  
                        sheet = hssfwb.GetSheetAt(0); //get first sheet from workbook  
                    }
                    else
                    {
                        XSSFWorkbook hssfwb = new XSSFWorkbook(stream); //This will read 2007 Excel format  
                        sheet = hssfwb.GetSheetAt(0); //get first sheet from workbook   
                    }
                    IRow headerRow = sheet.GetRow(0); //Get Header Row
                    int cellCount = headerRow.LastCellNum;
                    sb.Append("<table class='table'><tr>");
                    for (int j = 0; j < cellCount; j  )
                    {
                        NPOI.SS.UserModel.ICell cell = headerRow.GetCell(j);
                        if (cell == null || string.IsNullOrWhiteSpace(cell.ToString())) continue;
                        sb.Append("<th>"   cell.ToString()   "</th>");
                    }
                    sb.Append("</tr>");
                    sb.AppendLine("<tr>");
                    for (int i = (sheet.FirstRowNum   1); i <= sheet.LastRowNum; i  ) //Read Excel File
                    {
                        IRow row = sheet.GetRow(i);
                        if (row == null) continue;
                        if (row.Cells.All(d => d.CellType == CellType.Blank)) continue;
                        for (int j = row.FirstCellNum; j < cellCount; j  )
                        {
                            if (row.GetCell(j) != null)
                                sb.Append("<td>"   row.GetCell(j).ToString()   "</td>");
                        }
                        sb.AppendLine("</tr>");
                    }
                    sb.Append("</table>");
                }
            }
            return this.Content(sb.ToString());
        }
    }
  

Обратите внимание, что я не использовал модель

Фактический результат:

При нажатии кнопки предварительного просмотра пользовательский интерфейс снова отображается в div dvData. Я думаю, это потому, что я допускаю какую-то ошибку в соглашениях об именах, из-за которых он вызывает Index() контроллер вместо OnPostImport() .

Ожидаемый результат:

При нажатии кнопки предварительного просмотра должна отображаться таблица с отображением содержимого импортированного excel.

Ответ №1:

Причина

Вы отправляете запрос обработчику страницы Razor, ожидая, что действие контроллера его обработает. Другими словами, url это не соответствует потребностям.

Если вы предпочитаете использовать действие контроллера XYZController/OnPostImport , вам нужно изменить URL на [area]/[controller]/[action] . Например:

 $.ajax({ type: "POST",  url: "/BulkEditUserPermissions?обработчик = Импорт",
 url: "/XYZ/OnPostImport", // измените эту строку на правильный URL
 ...

Рабочая демонстрация:

введите описание изображения здесь

Комментарии:

1. PS: я хотел написать «/XYZ?handler= Import» в вопросе для универсального контроллера. Я внес исправление в вопрос, чтобы избежать путаницы для будущих читателей. PPS: Спасибо! Я также предложу такое же исправление в блоге, указав ссылку на этот комментарий.

2. @SonaliAgrawal В блоге используется шаблон WebApp ( Razor ), что означает, что автор создает страницу Razor (вместо контроллера) для обработки запроса