【问题标题】:How to allow only excel files on file upload [duplicate]如何在文件上传时只允许excel文件[重复]
【发布时间】:2020-05-09 22:01:38
【问题描述】:

我正在使用我在网上找到的一篇文章的 JavaScript /AngularJS 代码摘录。我对其进行了一些调整,因为原始帖子不适用于 IE 11,但除此之外,我正在使用它,因为我发现它。这段代码允许您将 Excel 文件上传和读取到 jQuery 数据表中。

我缺少一项要求,如果可能,我想寻求帮助。该要求是只允许上传 Excel 文件,任何其他类型的文件都不应该对用户“可见”。

这是我正在使用的代码:

AngularJS 控制器:

var app = angular.module('MyApp', []);
app.controller('MyController', ['$scope', '$http', function ($scope, $http) {

    $scope.SelectedFileForUpload = null;

    $scope.UploadFile = function (files) {
        $scope.$apply(function () {   
            $scope.Message = "";
            $scope.SelectedFileForUpload = files[0];
        })
    }

    //Parse Excel Data   
    $scope.ParseExcelDataAndSave = function () {

        var file = $scope.SelectedFileForUpload;

        if (file) {

            var reader = new FileReader();

            reader.onload = function (e) {

                var filename = file.name;
                // pre-process data
                var binary = "";
                var bytes = new Uint8Array(e.target.result);
                var length = bytes.byteLength;

                for (var i = 0; i < length; i++) {
                    binary += String.fromCharCode(bytes[i]);
                }

                // call 'xlsx' to read the file
                var data = e.target.result;
                var workbook = XLSX.read(binary, { type: 'binary', cellDates: true, cellStyles: true });
                var sheetName = workbook.SheetNames[0];
                var excelData = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);

                if (excelData.length > 0) {
                    //Save data   
                    $scope.SaveData(excelData);
                }
                else {
                    $scope.Message = "No data found";
                }            };



            }
            reader.onerror = function (ex) {
                console.log(ex);
            }

            reader.readAsArrayBuffer(file);
        }

html 视图:

<body ng-app="MyApp">
    <div class="container py-4" ng-controller="MyController">
        <div class="card">
            <div class="card-header bg-primary text-white">
                <h5>Common Council List</h5>
            </div>
            <div class="card-body">

                @* Upload Button *@
                <button style="margin-bottom:10px;" type="button" class="btn btn-primary rounded-0" data-toggle="modal" data-target="#myModal">
                    <i class="fa fa-file-excel-o"></i> Upload Excel File
                </button>

                @* Modal Window *@
                <div class="modal" id="myModal">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h4 class="modal-title">Upload Common Council Data</h4>
                                <button type="button" class="close" data-dismiss="modal">×</button>
                            </div>
                            <div class="modal-body">
                                <div class="col-md-12">
                                    <div class="input-group">
                                        <div class="custom-file">
                                            <input type="file" name="file" class="custom-file-input" onchange="angular.element(this).scope().UploadFile(this.files)" />
                                            <label class="custom-file-label" for="inputGroupFile04">Choose file</label>
                                        </div>
                                        <div class="input-group-append">
                                            <button class="btn btn-outline-secondary" type="button" ng-disabled="!SelectedFileForUpload" ng-click="ParseExcelDataAndSave()"><i class="fa fa-upload"></i> Upload</button>
                                        </div>
                                    </div>
                                    <span class="text-success">
                                        {{Message}}
                                    </span>
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-danger rounded-0" data-dismiss="modal" ng-click="clearText()">Close</button>
                            </div>
                        </div>
                    </div>
                </div>



                @* Main Table *@
                <table id="dataTable" class="table table-bordered table-striped" ;>
                    <thead>
                        <tr>
                            <th style="width: 90px;">Meeting ID</th>
                            <th style="width: 105px;">Agenda Item</th>
                            <th style="width: 85px;">Legistar ID</th>
                            <th>Title</th>
                        </tr>
                    </thead>
                </table>


            </div>
        </div>
    </div>
</body>

对此的任何帮助将不胜感激。

谢谢你, 伊拉斯莫

更新

html 标记

@* Modal Window *@
<div class="modal" id="myModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Upload Common Council Data</h4>
                <button type="button" class="close" data-dismiss="modal">×</button>
            </div>
            <div class="modal-body">
                <div class="col-md-12">
                    <div class="input-group">
                        <div class="custom-file">
                            <input type="file" name="file" class="custom-file-input" onchange="angular.element(this).scope().UploadFile(this.files)" />
                            <label class="custom-file-label" for="inputGroupFile04">Choose file</label>
                        </div>
                        <div class="input-group-append">
                            <button class="btn btn-outline-secondary" type="button" ng-disabled="!SelectedFileForUpload" ng-click="ParseExcelDataAndSave()" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />><i class="fa fa-upload"></i> Upload</button>
                        </div>
                    </div>
                    <span class="text-success">
                        {{Message}}
                    </span>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-danger rounded-0" data-dismiss="modal" ng-click="clearText()">Close</button>
            </div>
        </div>
    </div>
</div>

【问题讨论】:

  • “Excel 文件”是什么意思?您是指具有.xlsx 扩展名的文件吗?像 .xls 这样的旧 Excel 扩展怎么样? .csv 怎么样?具有非标准扩展名的 Excel 文件怎么样?如果只是将文件名限制为几个已知的扩展名那么简单,您可以在 HTML 级别使用 pattern attribute 在您的 &lt;file&gt; 标记上执行此操作。
  • 我在您更新的问题中看不到您的input 上的accept 属性。实际上,您应该将其应用于您的 input 而不是您的 button

标签: javascript angularjs


【解决方案1】:

您可以通过将accept 属性添加到您的input 来实现此目的,如下所示:

<input type="file" accept=".csv" />

但如果你想更清楚并接受所有版本的 excel,你应该改用这个:

<input type="file" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />

对于 Excel 文件 97-2003 (.xls),使用:

application/vnd.ms-excel

对于 Excel 文件 2007+ (.xlsx),使用:

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

另外,SO 中有同样的问题,您可以找到here

【讨论】:

  • 我试过这个,但是当我点击文件上传按钮时,我仍然可以看到所有类型的文件,而不仅仅是前面提到的那些。
  • @erasmocarlos 查看现场演示 here。如果您坚持第一个输入,您将只会看到 .csv 扩展文件。
  • @erasmocarlos 你有这样的输入:&lt;input type="file" name="file" class="custom-file-input" onchange="angular.element(this).scope().UploadFile(this.files)" /&gt; 所以你应该将accept 属性应用到这个而不是你的button 元素。它不适用于按钮。试一试,看看结果。
  • @erasmocarlos 请记住,按钮仅用于说明,主要工作在input 上,类型为file,所以这是用于上传的元素。您可以阅读this 了解更多信息。
  • 完全是我的错。我将接受添加到错误的元素中。我很抱歉。现在可以了。感谢您的帮助和耐心解释。
【解决方案2】:
<input type="file" accept=".xlsx, .xls, .csv"/>

【讨论】:

  • 我试过这个,但是当我点击文件上传按钮时,我仍然可以看到所有类型的文件,而不仅仅是前面提到的那些。
【解决方案3】:

如果您想要安全的东西,请检查文件前 n 个字节中的幻数。

阅读Magic Numbers

类似这样的:

const isXlsFile = (chunk) => {
    const types = [
        {
            ext: 'xls',
            mime: 'application/vnd.ms-excel',
            // magic numbers
            bytes: new Uint8Array([0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00])
        },
        {
            ext: 'xlsx',
            mime: 'application/vnd.ms-excel',
            bytes: new Uint8Array([0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00])
        }
    ]

    for (const type of types) {
        if (chunk.indexOf(type.bytes) === 0) return type;
    }

    return false;
};

这只是为了检查,如果它与您的类型匹配,则继续保存文件

【讨论】:

  • 好主意,但该网站没有列出 Excel 文件的神奇数字。
  • @kmoser 抱歉,我已经修复了链接
  • 你好@maxi,谢谢你,它看起来确实是最好的方法,但我不确定如何在我的代码中实现它。你有 JavaScript 代码示例吗?谢谢。
  • @erasmocarlos 我编辑了答案,看看它是否适合你
猜你喜欢
  • 2013-01-29
  • 1970-01-01
  • 2021-05-22
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多