React / Ant Design - unable to Upload XLSX

牧云@^-^@ 提交于 2019-12-11 16:48:31

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!