Javascript 如何在文件上载时仅允许excel文件

Javascript 如何在文件上载时仅允许excel文件,javascript,angularjs,Javascript,Angularjs,我使用的JavaScript/AngularJS代码摘自我在网上找到的一篇文章。我对它做了一些调整,因为原来的帖子在IE11上不起作用,但除此之外,我正在使用它,因为我发现了它。这段代码允许您将Excel文件上传并读取到jQuery数据表中 有一个要求,我错过了,并希望寻求帮助,如果可能的话。这一要求是只允许上传Excel文件,用户不应看到其他类型的文件 以下是我正在使用的代码: AngularJS控制器: var app = angular.module('MyApp', []); app.c

我使用的JavaScript/AngularJS代码摘自我在网上找到的一篇文章。我对它做了一些调整,因为原来的帖子在IE11上不起作用,但除此之外,我正在使用它,因为我发现了它。这段代码允许您将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>

您只需将accept属性添加到输入中即可实现此目的,如下所示:

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,则应使用以下版本:

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

应用程序/vnd.ms-excel 对于Excel文件2007+.xlsx,请使用:

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
此外,中还有相同的问题,以便您可以找到。

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

阅读

大概是这样的:

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文件是什么意思?你是说扩展名为.xlsx的文件吗?像.xls这样的旧Excel扩展如何?那么.csv呢?带非标准扩展名的Excel文件如何?如果只需将文件名限制为几个已知的扩展名,您就可以在HTML级别上使用标记上的来执行此操作。在更新的问题中,我看不到输入的accept属性。事实上,你应该将它应用到你的输入中,而不是你的按钮想法,但该网站没有列出Excel文件的神奇数字。@kmoser抱歉,我已经修复了linkHello@maxi,谢谢。这看起来确实是最好的方法,但我不确定如何在我的代码中实现它。您有JavaScript代码示例吗?谢谢。@erasmocarlos我编辑了答案,看看它是否适合你。我尝试过这个,但当我单击“文件上载”按钮时,我仍然可以看到所有类型的文件,而不仅仅是上面提到的文件。@erasmocarlos检查了实况演示。如果坚持使用第一个输入,您将只看到.csv扩展名文件。@erasmocarlos您有这样一个输入:因此您应该将accept属性应用于此输入,而不是应用于button元素。它对按钮不起作用。试试看结果。@erasmocarlos请记住,该按钮仅用于演示,主要工作是使用类型文件进行输入,因此在此处上载的元素就是该类型文件。你可以阅读更多信息。完全是我的错。我将accept添加到了错误的元素中。我道歉。现在可以了。谢谢你的帮助和耐心的解释。我试过了,但是当我点击文件上传按钮时,我仍然可以看到所有类型的文件,不仅仅是上面提到的文件。