我需要帮助如何使 react-dropzone NPM 包使上传的文件显示图像文件以外的文件的预览(*.png、*.jpg/jpeg、*.gif 等 - 这些都会生成预览就好)。
目前,当我使用 Dropzone 在 Web 表单上上传随附文件时,如果我上传图像文件(*.png、*.jpg 等),我们设置的预览就可以正常显示,并带有一个小缩略图已上传文件。 (见下图)
但是,如果我上传其他类型的文件,例如 MS-Outlook *.docx、*.xlsx,或者 Adobe Acrobat *.pdf,它只会给我一个空白框,其中包含损坏的文件图像和其他内容
alt="..."
我在那里输入的文本,在本例中为“上传的文件预览”。 (见下图)
我们使用的代码几乎是从 React Dropzon 网站上的 Preview 示例中逐字复制的,所以我想知道我是否在这里遗漏了一些东西?
这是我尝试过的—
react-dropzone
<Dropzone>
页面,将其设置为接受 any 文件类型,并使其能够使用来自 https://react-dropzone.js.org/#previews 的代码进行预览,在代码的 <aside>
部分底部有“预览”<Dropzone>
。<Dropzone>
。alt="..."
文本)。Dropzone 在文件顶部导入—
import React, { Component, /* useCallback */ } from "react";
...
import Dropzone from "react-dropzone";
...
缩略图的样式/CSS 代码 —
...
const thumbsContainer = {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
marginTop: 16
};
const thumb = {
display: "inline-flex",
borderRadius: 2,
border: "1px solid #eaeaea",
marginBottom: 8,
marginRight: 8,
width: 100,
height: 100,
padding: 4,
boxSizing: "border-box"
};
const thumbInner = {
display: "flex",
minWidth: 0,
overflow: "hidden"
};
const img = {
display: "block",
width: "auto",
height: "100%"
};
...
onDrop()
回调函数—
...
onDrop = (acceptedFiles, rejectedFiles) => {
let files = acceptedFiles.map(async file => {
let data = new FormData();
data.append("file", file);
let item = await axios
.post("form/upload", data, {
headers: {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
return Object.assign(file, {
preview: URL.createObjectURL(file),
filename: response.data.filename
});
})
.catch(err => {
let rejects = rejectedFiles.map(async file => {
let data = new FormData();
await data.append("file", file);
console.log("There was an error while attempting to add your files:", err);
console.log("The files that were rejected were:\n", rejects.join('\n'));
})
});
return item;
});
Promise.all(files)
.then(completed => {
let fileNames = completed.map(function(item) {
return item["filename"];
});
this.setState({ files: completed, fileNames: fileNames });
})
.catch(err => {
console.log('DROPZONE ERROR:', err);
});
};
...
在 React.JS 中使用
<Dropzone>
的实际 JSX 代码 return()
—
...
<Form.Field>
<label>Upload Files or Screenshots</label>
<Dropzone accept={acceptedFileTypes} onDrop={this.onDrop}>
{({ getRootProps, getInputProps, isDragActive }) => {
return (
<div
{...getRootProps()}
className={classNames("dropzone", {
"dropzone--isActive": isDragActive
})}
>
<input {...getInputProps()} />
{isDragActive ? (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">Drop Files Here.</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
) : (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">
Drag and Drop Supporting Files here to Upload.
</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
)}
</div>
);
}}
</Dropzone>
<aside style={thumbsContainer}>{thumbs}</aside>
</Form.Field>
...
预期行为 —
我会更喜欢所有文件类型来生成正确的预览。
我的设置 —
...那么,我是否做错了什么,导致除图像之外的其他文件的预览无法正常工作?除了图像文件之外,这不是其他功能吗?请指教。
还有几个问题 —
react-dropzone
的图像文件以外的文件生成预览,是否有办法让图像文件生成预览,但所有其他文件仅列出正在上传的文件名等,如某些您的 React Dropzone 网站 上的其他示例?如果是这样,当您将文件拖放到 <Dropzone>
上时,如何在两者之间切换以同时拥有两者?<Dropzone>
上,然后尝试拖动并第二次投放时,会擦除第一组上传的文件,并将其替换为刚刚投放到 <Dropzone>
上的新文件。有没有办法让 <Dropzone>
在每次将文件拖放到那里时累积添加文件,而不仅仅是清除以前的文件并替换为新文件?如果是这样,请问步骤是什么?我非常感谢任何建设性的答复。预先感谢您。
澄清一下,React-dropzone 并不是在页面上显示预览的。您正在使用图像标签来做到这一点。
现在,如果您要求显示所有文档文件类型的预览,您首先需要一个所需类型的解析器,因为浏览器不支持读取 pdf 以外的文档(.doc/.xlsx)。
类似于 react-doc-viewer。
这样您就可以读取上传的文件并使用包渲染器来显示文件
const docs = [
{ uri: "https://url-to-my-pdf.pdf" },
{ uri: require("./example-files/pdf.pdf") }, // Local File
];
...
<DocViewer documents={docs} />;
const thumbs = files.map(file => {
// Add other images types as needed
if(["image/png", "image/jpeg"].includes(file.type)){
return (
<div style={thumb} key={file.name}>
<div style={thumbInner}>
<img
src={file.preview}
style={img}
// Revoke data uri after image is loaded
onLoad={() => { URL.revokeObjectURL(file.preview) }}
/>
</div>
</div>
);
}
// Handling other file types
return (
<div style={thumb} key={file.name}>
<div style={thumbInner}>
<p>{file.name}</p
</div>
</div>
);
});
您可以为不同的文件 MIME 类型添加不同的条件。
文件 mime 类型的完整列表可以在 mdn docs
let fileNames = [...this.state.filenames,
...completed.map(function(item) {
return item["filename"];
})];
this.setState({files: [...this.state.files, ...completed], fileNames: fileNames });