问题
I'm learning React and currently using ant design for my upload button but somehow it won't work ( it works normally without the design.
My original code(working version):
export default ({ addItem }) => {
return (
<label className="btn">
<input
type="file"
onChange={e => {
var reader = new FileReader();
reader.onload = event => {
var data = event.target.result;
var workbook = XLSX.read(data, {
type: "binary",
});
workbook.SheetNames.forEach(sheetName => {
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
XL_row_object.forEach(x => {
addItem(x.sku, x.description, parseInt(x.quantity), parseFloat(x.cost));
});
});
};
if (e.target.files[0]) {
reader.readAsBinaryString(e.target.files[0]);
}
}}
/>
</label>
);
};
the mistakes I made:
(in additional, my upload component only takes 4 columns/values: sku, description, quantity and unit_price)
import React, { Component } from "react";
import * as XLSX from "xlsx";
import { Button, Icon, message } from "antd";
import "./styles.css";
export default class UploadItem extends Component {
onImportExcel = (file, addItem) => {
const { files } = file.target;
const fileReader = new FileReader();
fileReader.onload = event => {
try {
const { result } = event.target;
const workbook = XLSX.read(result, { type: "binary" });
let data = [];
for (const Sheet in workbook.Sheets) {
// var XL_row_object =
XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if (workbook.Sheets.hasOwnProperty(Sheet)) {
data = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[Sheet]);
data.forEach(x => {
addItem(x.sku, x.description, parseInt(x.quantity), parseFloat(x.cost));
});
}
}
message.success("upload success!");
console.log(data);
} catch (e) {
message = message.error("file type is incorrect!");
}
};
fileReader.readAsBinaryString(files[0]);
};
render() {
return (
<div style={{ marginTop: 100 }}>
<Button className="upload-wrap">
<Icon type="upload" />
<input className="file-uploader" type="file" accept=".xlsx, .xls" onChange={this.onImportExcel} />
<span className="upload-text">Upload files</span>
</Button>
<p className="upload-tip">Supports files in .xlsx, .xls format</p>
</div>
);
}
}
回答1:
There's a couple things... I'd refactor this so the XLS handling lives outside the component (as it doesn't really need to be there), to begin with.
Then, the onImportExcel
handler needs to simply grab the file selected, run it through the function and we're good to go.
I didn't do anything about the message
things -- those would also belong inside a component, but at that point I'd also refactor importExcel
to return a promise. That's beyond the scope of this question though, I think :)
import React, { Component } from "react";
import * as XLSX from "xlsx";
import { Button, Icon, message } from "antd";
import "./styles.css";
const importExcel = (file, addItem) => {
const fileReader = new FileReader();
fileReader.onload = event => {
try {
const { result } = event.target;
const workbook = XLSX.read(result, { type: "binary" });
for (const Sheet in workbook.Sheets) {
// var XL_row_object =
XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if (workbook.Sheets.hasOwnProperty(Sheet)) {
data = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[Sheet]);
data.forEach(x => {
addItem(x.sku, x.description, parseInt(x.quantity), parseFloat(x.cost));
});
}
}
message.success("upload success!");
} catch (e) {
message = message.error("file type is incorrect!");
}
};
fileReader.readAsBinaryString(file);
};
export default class UploadItem extends Component {
onImportExcel = event => {
const { files } = event.target;
if (files.length === 1) {
// Process a file if we have exactly one
importExcel(
files[0],
// Not sure what you want to do with the data, so let's just log it
(sku, description, quantity, cost) => console.log(sku, description, quantity, cost),
);
}
};
render() {
return (
<div style={{ marginTop: 100 }}>
<Button className="upload-wrap">
<Icon type="upload" />
<input className="file-uploader" type="file" accept=".xlsx, .xls" onChange={this.onImportExcel} />
<span className="upload-text">Upload files</span>
</Button>
<p className="upload-tip">Supports files in .xlsx, .xls format</p>
</div>
);
}
}
来源:https://stackoverflow.com/questions/53923927/react-ant-design-unable-to-upload-xlsx