Есть ли способ загружать и редактировать объемные данные, используя файл Excel в реакции, используя handsontable в качестве редактора - PullRequest
0 голосов
/ 25 апреля 2020

То, чего я достиг, так это то, что я могу загружать файл, извлекать информацию и просматривать его во внешнем интерфейсе, используя пакет-обертку реагирования с поддержкой handstatable в реакции js

ниже приведены фотографии того, что я пока сделал достиг

ДОБЫВАЮЩАЯ И ПРОВЕРЯЮЩАЯ ИНФОРМАЦИЯ: ДОБЫВАЮЩИЕ ДАННЫЕ И ВАЛИДАЦИЯ

ОШИБКА ПРОИЗВОДИТСЯ, КОГДА Я ОБНОВЛЯЮ ПОЛЕ В HANDSONTABLE

ПРИМЕЧАНИЕ. Я использую избыточность в качестве центрального хранилища объекта JSON, который я проанализировал из файла excel с использованием библиотеки XLSX

ЗДЕСЬ КОД:

const initialState = {
  ErrorMsg: null,
  SuccessMsg: null,
  isExcelLoaded: true,
  isExcelLoading: true,
  invalidFields: [],
};

class ExcelBook extends Component {
  constructor(props) {
    super(props);

    this.state = initialState;
    this.id = "hot";
    this.hotSettings = {
      data: this.props.reduxStore.excel.data,
      licenseKey: "non-commercial-and-evaluation",
      beforeChange: this.onBeforeHotChange,
      colHeaders: true,
      nestedHeaders: [

      ],
      width: "100%",
      height: 320,
      rowHeaders: true,
      colHeaders: true,
      columns: [
        {
          renderer: function (
            instance,
            td,
            row,
            col,
            prop,
            value,
            cellProperties
          ) {
            const escaped = Handsontable.helper.stringify(value);
            let img = null;
            if (!escaped) {
              td.style.backgroundColor = "RED";
              td.style.color = "#ffffff";
              Handsontable.dom.empty(td);
            } else {
              Handsontable.renderers.TextRenderer.apply(this, arguments);
            }

            return td;
          },
        },
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
      ],
    };
    this.hotTableComponent = React.createRef();
  }

  updateInvalidField = (index, fieldName, newValue, regex, changes, source) => {
    let invalidFields = [...this.state.invalidFields[index]["invalidFields"]];

    if (fieldName === "PrdouctDescription" || fieldName === "cName") {
      const filteredarr = invalidFields.filter((item) => item !== fieldName);

      invalidFields = filteredarr;

      this.setState({ invalidFields });
      this.props.bulkediting(changes, source);
      this.hotTableComponent.current.hotInstance.loadData(
        this.props.reduxStore.excel.data
      );
    } else if (regex.test(newValue)) {
      const filteredarr = invalidFields.filter((item) => item !== fieldName);

      invalidFields[index]["invalidFields"] = filteredarr;
      invalidFields[index][fieldName] = newValue;
      this.setState({ invalidFields });
    } else {
      invalidFields.indexOf(fieldName) === -1
        ? invalidFields.push(fieldName)
        : console.log(1);

      invalidFields[index]["invalidFields"] = invalidFields;
      invalidFields[index][fieldName] = newValue;
      this.setState({ invalidFields });
    }
  };
  componentDidUpdate(prevProps) {
    const { error, success } = this.props;

    if (error !== prevProps.error) {
      if (error.id === "EXCEL_ERROR") {
        this.setState({ ErrorMsg: error.msg });
      }
    }
    if (success !== prevProps.success) {
      if (success.id === "EXCEL_SUCCESS") {
        this.setState({
          SuccessMsg: success.msg,
          invalidFields: [],

          isExcelLoaded: false,
          isExcelLoading: false,
        });
        window.scrollTo(0, 0);
      }
    }
  }


  //ant functions//
  fileProcess = async (e) => {
    try {
      this.setState({
        isExcelLoading: true,
      });
      let contentBuffer = await this.onchangeHanglerExcelFile(e);

      const arryDatasource = [];
      const invalidFields = [];

      contentBuffer.map((p, i) => {
        arryDatasource.push([
          p.cName,
          p.cEmail,
          p.cPhone,
          p.cAddress,
          p.cCity,
          p.cAmount,
          p.cWeight,
          p.cStypes,
          p.cPieces,
          p.cFragile,
          p.cMunit,
          p.cHeight,
          p.cWidth,
          p.cLength,
          p.productDescription,
        ]);
      });

      contentBuffer.map((inf, i) => {
        invalidFields.push({
          invalidFields: inf.invalidFields,
        });
      });
      this.state.invalidFields = invalidFields;
      this.props.bulkadd(arryDatasource);
      this.setState({
        isExcelLoading: false,
        isExcelLoaded: true,
        invalidFields: invalidFields,
      });
      console.log(invalidFields);
      this.hotTableComponent.current.hotInstance.loadData(arryDatasource);
    } catch (err) {
      console.log(err);
    }
  };
  onBeforeHotChange = (changes, source) => {
    let ROW = changes[0][0];
    let COULMN = changes[0][1];
    let UPDATED_VALUE = changes[0][3];

    switch (COULMN) {
      case 0:
        {
          if (UPDATED_VALUE) {
            this.updateInvalidField(
              ROW,
              "cName",
              UPDATED_VALUE,
              /^[a-zA-Z ]*$/i,
              changes,
              source
            );
          }
        }

        break;
      case 1:
        {
        }
        break;
      case 2:
        {
        }
        break;
      case 3:
        {
        }
        break;
      case 4:
        {
        }
        break;
      case 5:
        {
        }
        break;
      case 6:
        {
        }
        break;
      case 7:
        {
        }
        break;
      case 8:
        {
        }
        break;
      case 9:
        {
        }
        break;
      case 10:
        {
        }
        break;
      case 11:
        {
        }
        break;
      case 12:
        {
        }
        break;
      case 13:
        {
        }
        break;
      case 14:
        {
        }
        break;
      default:
        break;
    }
  };
  onchangeHanglerExcelFile = (e) => {
    const onchangeExcelFileValidator = (
      regex,
      fieldName,
      excelRowObject,
      combo,
      data,
      i,
      fieldindex,
      comparedValues
    ) => {
      switch (combo) {
        case "cName":
          {
            if (
              data[i][fieldindex] === undefined ||
              data[i][fieldindex] === null
            ) {
              excelRowObject[`${fieldName}`] = data[i][fieldindex];
              excelRowObject["invalidFields"].push(`${fieldName}`);
            } else {
              excelRowObject[`${fieldName}`] = data[i][fieldindex];
            }
          }
          break;
        case false:
          {
            if (!regex.test(data[i][fieldindex])) {
              excelRowObject[`${fieldName}`] = data[i][fieldindex];
              excelRowObject["invalidFields"].push(`${fieldName}`);
            } else {
              excelRowObject[`${fieldName}`] = data[i][fieldindex];
            }
          }

          break;
        case true:
          {
            let cvalue;
            if (data[i][fieldindex]) {
              cvalue = data[i][fieldindex].replace(/\s/g, "").toLowerCase();
            } else {
              cvalue = "";
            }
            const captalValue =
              cvalue.charAt(0).toUpperCase() + cvalue.slice(1);

            if (comparedValues.includes(captalValue) === false) {
              excelRowObject[`${fieldName}`] = data[i][fieldindex];
              excelRowObject["invalidFields"].push(`${fieldName}`);
            } else {
              const cvalue = data[i][fieldindex]
                .replace(/\s/g, "")
                .toLowerCase();
              const captalValue =
                cvalue.charAt(0).toUpperCase() + cvalue.slice(1);
              excelRowObject[`${fieldName}`] = captalValue;
            }
          }
          break;
        case "fragile":
          {
            if (
              data[i][fieldindex] === "Y" ||
              data[i][fieldindex] === "N" ||
              data[i][fieldindex] === "y" ||
              data[i][fieldindex] === "n"
            ) {
              switch (data[i][fieldindex]) {
                case "Y":
                case "y":
                  {
                    excelRowObject[`${fieldName}`] = "YES";
                  }
                  break;

                case "N":
                case "n":
                  {
                    excelRowObject[`${fieldName}`] = "NO";
                  }
                  break;

                default:
                  break;
              }
            } else {
              excelRowObject[`${fieldName}`] = "NO";
              excelRowObject["invalidFields"].push(`${fieldName}`);
            }
          }
          break;
        default:
          break;
      }
    };
    return new Promise((resolve, reject) => {
      const cities = this.props.reduxStore.cities.fetchedCities.docs;

      const shipmentTypes = this.props.reduxStore.stypes.fetchedStypes.docs;
      const munits = this.props.reduxStore.munit.fetchedMunit.docs;

      var reader = new FileReader();
      let excelData = [];
      reader.readAsArrayBuffer(e.target.files[0]);

      reader.onload = function (e) {
        var data = e.target.result;
        var data = new Uint8Array(reader.result);
        var wb = XLSX.read(data, { type: "array" });

        var first_worksheet = wb.Sheets[wb.SheetNames[0]];
        var data = XLSX.utils.sheet_to_json(first_worksheet, {
          header: 1,
        });

        let i;
        let j;
        let k;
        let l;

        const comparedWithCities = [];
        const comparedWithShipmentTypes = [];
        const compareWithMunits = [];
        for (j = 0; j < cities.length; j++) {
          comparedWithCities.push(cities[j].cityName);
        }
        for (k = 0; k < shipmentTypes.length; k++) {
          comparedWithShipmentTypes.push(shipmentTypes[k].shipmentType);
        }
        for (l = 0; l < munits.length; l++) {
          compareWithMunits.push(munits[l].unit);
        }

        if (
          data[0][0] === "CONSIGNEE NAME" &&
          data[0][1] === "CONSIGNEE EMAIL" &&
          data[0][2] === "CONSIGNEE PHONE" &&
          data[0][3] === "CONSIGNEE ADDRESS" &&
          data[0][4] === "DESIGNATION" &&
          data[0][5] === "AMOUNT" &&
          data[0][6] === "DESCRIPTION" &&
          data[0][7] === "WEIGHT" &&
          data[0][8] === "SHIPMENT TYPE" &&
          data[0][9] === "PIECES" &&
          data[0][10] === "FRAGILE" &&
          data[0][11] === "DIMENTIONS"
        ) {
          if (data.length <= 501) {
            for (i = 1; i < data.length; i++) {
              const excelRowObject = { invalidFields: [] };

              onchangeExcelFileValidator(
                null,
                "cName",
                excelRowObject,
                "cName",
                data,
                i,
                0
              );

              onchangeExcelFileValidator(
                /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
                "cEmail",
                excelRowObject,
                false,
                data,
                i,
                1
              );
              onchangeExcelFileValidator(
                /^3[0-9+]{9}$/i,
                "cPhone",
                excelRowObject,
                false,
                data,
                i,
                2
              );
              onchangeExcelFileValidator(
                /^[a-zA-Z0-9 _/#&+-||]{25,}$/i,
                "cAddress",
                excelRowObject,
                false,
                data,
                i,
                3
              );

              onchangeExcelFileValidator(
                null,
                "cCity",
                excelRowObject,
                true,
                data,
                i,
                4,
                comparedWithCities
              );
              onchangeExcelFileValidator(
                /^[0-9]*$/,
                "cAmount",
                excelRowObject,
                false,
                data,
                i,
                5
              );
              excelRowObject["productDescription"] = data[i][6];

              onchangeExcelFileValidator(
                /^[0-9]*$/,
                "cWeight",
                excelRowObject,
                false,
                data,
                i,
                7
              );

              onchangeExcelFileValidator(
                null,
                "cStypes",
                excelRowObject,
                true,
                data,
                i,
                8,
                comparedWithShipmentTypes
              );

              onchangeExcelFileValidator(
                /^[0-9]*$/,
                "cPieces",
                excelRowObject,
                false,
                data,
                i,
                9
              );

              onchangeExcelFileValidator(
                null,
                "cFragile",
                excelRowObject,
                "fragile",
                data,
                i,
                10
              );

              const dimentionArr = data[i][11].split(",");
              let munit;

              if (dimentionArr[0]) {
                munit = dimentionArr[0].replace(/\s/g, "").toLowerCase();
              } else {
                munit = "";
              }

              const capitalMunit =
                munit.charAt(0).toUpperCase() + munit.slice(1);

              if (compareWithMunits.includes(capitalMunit) === false) {
                excelRowObject["cMunit"] = "CM";
                excelRowObject["invalidFields"].push("cMunit");
              } else {
                const munit = dimentionArr[0].replace(/\s/g, "").toLowerCase();
                const capitalMunit =
                  munit.charAt(0).toUpperCase() + munit.slice(1);
                excelRowObject["cMunit"] = capitalMunit;
              }

              if (!/^[0-9]*$/.test(parseInt(dimentionArr[1]))) {
                excelRowObject["cHeight"] = dimentionArr[1];
                excelRowObject["invalidFields"].push("cHeight");
              } else {
                excelRowObject["cHeight"] = parseInt(dimentionArr[1]);
              }
              if (!/^[0-9]*$/.test(parseInt(dimentionArr[2]))) {
                excelRowObject["cWidth"] = dimentionArr[2];
                excelRowObject["invalidFields"].push("cWidth");
              } else {
                excelRowObject["cWidth"] = parseInt(dimentionArr[2]);
              }
              if (!/^[0-9]*$/.test(parseInt(dimentionArr[3]))) {
                excelRowObject["cLength"] = dimentionArr[3];
                excelRowObject["invalidFields"].push("cLength");
              } else {
                excelRowObject["cLength"] = parseInt(dimentionArr[3]);
              }

              excelData.push(excelRowObject);
            }
            resolve(excelData);
          } else {
            alert("Only 20 packets are allowed at one time ");
            return reject;
          }
        } else {
          alert("Invalid File Format");
        }
      };
      reader.onerror = reject;
    });
  };

  render() {
    console.log(this.state.invalidFields);
    const { selectedRowKeys } = this.state;
    const options = [];
    this.props.cities.fetchedCities.docs.map((p) => {
      options.push({ value: p._id, label: p.cityName });
    });

    const optionsShipmentTypes = [];
    this.props.stype.fetchedStypes.docs.map((p) => {
      optionsShipmentTypes.push({
        value: p._id,
        label: p.shipmentType,
      });
    });

    const optionsUnit = [];
    this.props.munit.fetchedMunit.docs.map((p) => {
      optionsUnit.push({ value: p._id, label: p.unit });
    });
    let alert;
    if (this.state.ErrorMsg !== null) {
      alert = (
        <Alert color="danger" contentClassName="bg-gradient-danger">
          {this.state.ErrorMsg.message}
        </Alert>
      );
    } else {
      alert = null;
    }
    let smsg;
    if (this.state.SuccessMsg !== null) {
      smsg = (
        <UncontrolledAlert color="success" fade={true}>
          <span className="alert-inner--icon"></span>{" "}
          <span className="alert-inner--text">
            <strong>SUCCESS</strong> {this.state.SuccessMsg.message}
          </span>
        </UncontrolledAlert>
      );
    } else {
      smsg = null;
    }

    return (
      <>
        <Header
          pageType="innerPage"
          headerClass="header bg-gradient-success pb-8 pt-5 pt-md-8"
        />
        {/* Page content */}
        <Container className="mt--7" fluid>
          {/* Table */}
          <Row>
            <div className="col">
              <Card className="shadow">
                <CardHeader className="border-0">
                  <h3 className="mb-0">Excel Booking</h3>
                </CardHeader>
                <CardBody align="center">
                  <div align={"center"}>
                    {alert} {smsg}
                  </div>


                  {this.state.isExcelLoaded &&
                  this.state.isExcelLoading === false ? (
                    <div>
                      <Button
                        className="btn-icon btn-3"
                        disabled={
                          this.props.isSendingRequest.isSendingRequest
                            ? true
                            : false
                        }
                        color="success"
                        type="button"
                        onClick={() => {
                          this.handleSubmit();
                        }}
                      >
                        <span className="btn-inner--icon">
                          <i className="fa fa-check" />
                        </span>
                        <span className="btn-inner--text">Proceed</span>
                      </Button>
                      <Button
                        className="btn-icon btn-3"
                        disabled={
                          this.props.isSendingRequest.isSendingRequest
                            ? true
                            : false
                        }
                        style={{ backgroundColor: "#6b03d3", color: "#ffffff" }}
                        type="button"
                        onClick={() => {
                          this.addRowItem();
                        }}
                      >
                        <span className="btn-inner--icon">
                          <i className="fa fa-plus-circle" />
                        </span>
                        <span className="btn-inner--text">Add Row</span>
                      </Button>

                      <Button
                        className="btn-icon btn-3"
                        disabled={
                          this.props.isSendingRequest.isSendingRequest
                            ? true
                            : false
                        }
                        style={{ backgroundColor: "red", color: "#ffffff" }}
                        type="button"
                        onClick={() => {
                          this.setState(initialState);
                        }}
                      >
                        <span className="btn-inner--icon">
                          <i className="fa fa-minus-circle" />
                        </span>
                        <span className="btn-inner--text">
                          Remove ExcelSheet
                        </span>
                      </Button>
                    </div>
                  ) : (
                    <div>
                      <a href="/sample.xlsx" download>
                        <Button
                          className="btn-icon btn-3"
                          color="primary"
                          type="button"
                        >
                          <span className="btn-inner--icon">
                            <i className="fa fa-download" />
                          </span>
                          <span className="btn-inner--text">Sample File</span>
                        </Button>
                      </a>
                      <label
                        htmlFor="uploadExcel"
                        className="btn btn-success"
                        style={{ margin: "20px" }}
                      >
                        <span className="btn-inner--icon">
                          <i className="fa fa-upload" />
                        </span>
                        <span className="btn-inner--text">Upload Excel</span>
                      </label>
                      <input
                        hidden
                        type="file"
                        id="uploadExcel"
                        onChange={(value) => {
                          this.fileProcess(value);
                        }}
                      ></input>
                    </div>
                  )}

                  <div style={{ padding: "20px" }}></div>
                </CardBody>
                <div style={{ padding: "5%" }}>
                  {this.state.isExcelLoaded ? (
                    <div id="hot-app">
                      <HotTable
                        ref={this.hotTableComponent}
                        id={this.id}
                        settings={this.hotSettings}
                      />
                    </div>
                  ) : (
                    <div>Select Excel File</div>
                  )}
                </div>
              </Card>
            </div>
          </Row>
        </Container>
      </>
    );
  }
}
const mapStateToProps = (state) => {
  return {
    reduxStore: state,
    cities: state.cities,
    munit: state.munit,
    stype: state.stypes,
    error: state.error,
    success: state.success,
    isSendingRequest: state.request,
  };
};
const mapDispatchToProps = (dispatch) => {
  return {
    getAllCities: () => {
      dispatch(getcities());
    },
    getAllmunits: () => {
      dispatch(getmunit());
    },
    getAllstypes: () => {
      dispatch(getstypes());
    },
    loaduser: () => {
      dispatch(loadUser());
    },
    bulkediting: (change, source) => {
      dispatch(bulkEditing(change, source));
    },
    bulkadd: (data) => {
      dispatch(bulkAdd(data));
    },
    sentRequestToServer: (data) => {
      dispatch(excelBooking(data));
    },
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(ExcelBook);

ЧТО НУЖНО, ЧТОБЫ ДОСТИГНУТЬ SOO FAR:

ЦЕЛИ:

1 - ЗАГРУЗКА ДАННЫХ С ИСПОЛЬЗОВАНИЕМ ФАКСА EXCEL (ВЫ МОЖЕТЕ ИСПОЛЬЗОВАТЬ ЛИСТЫ XLSX PARSER ДЛЯ ПАРСИРОВАНИЯ EXCEL TO JSON)

2 - ПОЛЬЗОВАТЕЛЬ МОЖЕТ РЕДАКТИРОВАТЬ ДАННЫЕ В РАСПИСАНИИ (ВЫ МОЖЕТЕ ИСПОЛЬЗОВАТЬ HANDSONTABLE ДЛЯ РЕАГИРОВАНИЯ JS ИЛИ ИЛИ ПОХОЖУЮ БИБЛИОТЕКУ https://handsontable.com/docs/7.4.2/frameworks-wrapper-for-react-installation.html)

3 - КОГДА ПОЛЬЗОВАТЕЛЬ ЗАГРУЗИТ ФАЙЛ EXCEL, ЭТО ДОЛЖЕН БЫТЬ ПРЕДОСТАВЛЕНО В HANDSONTABLE И НЕОБХОДИМО БЫТЬ НЕКОТОРЫМИ ПРАВИЛАМИ ВАЛИДАЦИИ, НЕКОТОРЫЕ РЕГИОНЫ И НЕКОТОРЫЕ УСЛОВИЯ, КАК ЕСЛИ ПОЛЬЗОВАТЕЛЬ В ГОРОДЕ ВИДЕН В НЕПРАВИЛЬНО, И НЕ СУЩЕСТВУЕТ В ГОСУДАРСТВЕ, КОТОРОЕ ЯВЛЯЕТСЯ ИЗ БАЗЫ ДАННЫХ О КОМПОНЕНТДИДМОЙНТЕ, КОТОРОЕ ПОЛЬЗУЕТСЯ ИМЕННО ПОЛЬЗОВАТЬСЯ ИМЕННО ПОЛЬЗОВАТЬСЯ ЗДРАВООХРАНЕНИЕМ ПОЛЬЗОВАТЕЛЯ ТАКЖЕ ДОЛЖЕН БЫТЬ КРАСНЫЙ ВЫДЕЛЕННЫЙ КЛЕТОК HANDSONTABLE ТАМ, КОГДА ПОЛЬЗОВАТЕЛЬ ПРАВИЛЬНЫЙ КЛЕТОК ДОЛЖЕН БЫТЬ НОРМАЛЬНЫМ, КАК ДРУГОЙ.

4 - ТАМ ДОЛЖЕН БЫТЬ НЕКОТОРЫЙ ЗАКЛЮЧИТЕЛЬНЫЙ ОБЪЕКТ, КОТОРЫЙ СОГЛАСНО ВСЕХ ДАННЫХ ПОЛЬЗОВАТЕЛЬ ИЗМЕНИТ ЧТО-ТО.

5 - В ЭТОМ ОБЪЕКТЕ СЛЕДУЕТ БЫТЬ НЕДЕЙСТВИТЕЛЬНО, ФАЙЛЫ РАБОТЫ ТАКЖЕ ДЛЯ КАЖДОГО РЯДА, КАК ПОСЛЕ ТОГО, КАК МЫ ПОЛЬЗУЕМСЯ ПЕРЕДАТЬ ПОСЛЕ ЭТИХ ДАННЫХ, ПОСЛЕ ТОГО, КАК МЫ ДОЛЖНЫ ПРОВЕРИТЬ ЭТО Недопустимый массив равен 0, если в массиве есть полевые имена, которые пользователь должен исправить.

6 - Мы также должны использовать PU SH и массив недействительных фильтров при наборе текста в каждой строке КАК ЕСЛИ ЗНАЧЕНИЕ ДЕЙСТВИТЕЛЬНО, МЫ ДОЛЖНЫ ФИЛЬТРОВАТЬ И УДАЛИТЬ, ЧТО УКАЗАНО C EL Элемент из массива, и если пользователь имеет тип и лево с недействительным значением, как неправильное письмо, то ячейка также должна быть красной, а имя того поля также добавлено в недействительное поле.

Я пытался выяснить, с какой проблемой я сталкиваюсь Я хочу достичь и того, чего я достиг, настолько далеко, если любой вопрос, касающийся любой путаницы, простит меня и задаст мне, я буду стараться изо всех сил, чтобы прояснить, и каждый пункт экспертам спасибо

...