我正在使用multer的gridfs存储引擎将文件从浏览器上传到mongodb数据库。
我需要允许用户上传csv和json文件类型(以后再上传)。在将文件上传到数据库之前,如何检查文件类型是否为csv并将其转换为json。
我使用了多个npm软件包,例如csvtojson,papaparse。使用papaparse我可以将文件类型转换为json,但是我似乎无法在存储/上传中访问它。
这是我到目前为止所做的。
const storage = new GridFsStorage({
url: "",
file: (req, file) => {
return new Promise((resolve, reject) => {
const filename = `${new Date()
.toJSON()
.slice(0, 10)
.split("-")
.reverse()
.join(".")} - ${file.originalname}`;
const fileInfo = {
filename,
bucketName: "uploads"
};
resolve(fileInfo);
});
}
});
const upload = multer({
storage,
fileFilter: function(req, file, cb) {
var filetypes = /json|csv/;
var mimetype = filetypes.test(file.mimetype);
var extname = filetypes.test(path.extname(file.originalname).toLowerCase());
if (mimetype && extname) {
return cb(null, true);
}
cb({
fileTypeError: "File upload only supports the following filetypes - " + filetypes
});
}
});
const fileUpload = upload.single("file");
// create mongo connection
const conn = mongoose.createConnection(mongoURI);
// Init gfs
let gfs;
conn.once("open", () => {
console.log("connection open");
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection("uploads");
});
app.use(bodyParser.json({
limit: "50mb"
}));
app.use(
bodyParser.urlencoded({
extended: true,
limit: "50mb",
parameterLimit: 1000000
})
);
// @route POST api/logs/upload
// @desc Upload file
// @access Public
app.post("/api/logs/upload", (req, res) => {
fileUpload(req, res, function(err) {
if (err) {
return res.status(501).json(err);
}
//send back file data
//req.body is empty here too
res.json({
file: req.file
});
});
});
onSubmit(e) {
const { addLogFile } = this.props;
e.preventDefault();
let formData = new FormData();
const file = this.fileInput.files[0];
console.log(file);
if (file.type === "application/vnd.ms-excel") {
Papa.parse(file, {
header: true,
complete: function(results) {
file.csv = results.data;
formData.append("file", file);
addLogFile(formData);
}
});
} else if (file.type === "application/json") {
formData.append("file", file);
addLogFile(formData);
} else {
alert("not supported");
}
// clear file input
document.getElementById("file").value = "";
}
render() {
return (
<div className="logs">
<form encType="multipart/form-data" onSubmit={this.onSubmit}>
<input
name="file"
type="file"
id="file"
ref={input => {
this.fileInput = input;
}}
onChange={this.onChange}
required
accept="application/json, .csv"
/>
<button>
Upload
</button>
</form>
</div>
);
}
在哪里可以访问文件详细信息和csv文件?还是有更好的方法来解决这个问题?
答案 0 :(得分:0)
您必须创建自己的存储引擎(https://github.com/expressjs/multer/blob/master/StorageEngine.md)
在_handleFile
方法中,您可以访问文件路径,该路径可用于转换文件。然后,如果您想使用gridfs,我建议绕过gridfs-storage-engine
模块(顺便说一句,自2016年以来未曾使用过)。只要看一下https://github.com/ISMAELMARTINEZ/gridfs-storage-engine/blob/master/lib/GridfsStorage.js#L47上的代码,就可以做到:
MyCustomStorage.prototype._handleFile = function _handleFile (req, file, cb) {
this.getDestination(req, file, function (err, path) {
if (err) return cb(err)
const writestream = gfs.createWriteStream({
filename: file.originalname,
metadata: req.body,
content_type: file.mimetype
});
file.stream.pipe(csv()).pipe(writestream);
writestream.on('close', function (file) {
console.log('gridfs-storage-engine: saved', file);
cb(null, { gridfsEntry: file });
});
});
}