直接说需求:需要实现在文件上传面板中限制需要的文件格式,并且不想展示“所有文件”这个选项,应该怎么做嘞?效果如下图:
这里用到了 window.showOpenFilePicker 方法实现,首先定义接受的格式及限制:
const pickerOpts = {
types: [
{
description: 'Files',
accept:
{
'application/pdf': ['.pdf'],
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx', '.doc'],
'application/vnd.ms-excel': ['.xls'],
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx','.ppt']
}
}
],
excludeAcceptAllOption: true,
multiple: state.allowMultipleUpload
};
这里如果按照下面这种写法来写,会导致出现.ppa和.dot格式的文件格式:
const pickerOpts = {
types: [
{
description: 'Files',
accept:
{
'application/pdf': ['.pdf'],
'application/vnd.ms-word': ['.doc'],
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
'application/vnd.ms-excel': ['.xls'],
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
'application/vnd.ms-powerpoint': ['.ppt'],
'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx']
}
}
],
excludeAcceptAllOption: true,
multiple: state.allowMultipleUpload
};
下面是实现效果的关键代码:
try {
if (window.showOpenFilePicker) {
const fileHandles = await window.showOpenFilePicker(pickerOpts);
const fileDatas = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
handleFileInput(fileDatas); // 这里进行后续的上传逻辑
} else {
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.accept = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx';
input.onchange = () => {
if (input.files) {
handleFileInput(Array.from(input.files)); // 这里进行后续的上传逻辑
}
};
input.click();
}
} catch (err) {
console.log(err);
}
这里为什么是加了if..else,因为Safari浏览器和火狐浏览器不支持 window.showOpenFilePicker,因此需要向下兼容,使用原生的方法,不过这两个浏览器无法去掉“所有文件”这个选项,效果如下: