反应js读取文档/docx文件的文本

2022-07-21 00:00:00 file reactjs docx javascript docxtemplater

我需要读取由用户上载的文档/docx文件的内容。

我已尝试将jszipdocxtemplater一起使用,但无法读取文件。

如果除了docs/docx文件之外,它还可以读取txt文件,那就太好了。

我有一个这样的docx文件:

Io sottoscritto/a __NOME__
nato a __CITTA_NASCITA__(__SIGLA_CITTA_NASCITA__) il __DATA_NASCITA__
residente a __RESIDENZA__   in via __VIA_RESIDENZA__    n __NUMERO_RESIDENZA__.

你能帮我一下吗?

链接:https://codesandbox.io/s/lively-butterfly-ey8og?file=/src/App.js:0-2711

编码:

import React, { useState } from "react";
import { TextField } from "@material-ui/core";
import Docxtemplater from "docxtemplater";
import JSZip from "jszip";

export default function App() {
  const [state, setState] = useState({
    original: [],
    edit: [],
    arrayO: [],
    arrayE: []
  });
  const { original, edit, arrayO, arrayE } = state;

  const showFile = async (e) => {
    e.preventDefault();
    const reader = new FileReader();
    reader.onload = async ({ target: { result } }) => {
      /*const reg = /__[A-Z]+(?:_[A-Z]+)*__/gi;
      const row = result.split("
");
      let arrayO = result.match(reg);
      setState((prev) => ({
        ...prev,
        original: row,
        edit: row,
        arrayO,
        arrayE: arrayO
      }));*/

      var zip = new JSZip();
      zip.loadAsync(result).then(function (zip) {
        var doc = new Docxtemplater().loadZip(zip);
        var text = doc.getFullText();
        console.log(text);
      });
    };
    reader.readAsText(e.target.files[0]);
  };

  const onChange = (value, label, key) => {
    console.log(value, label, key);
    console.log(
      original.map((e, k) =>
        e.includes(label)
          ? value === ""
            ? label
            : e.replace(label, value)
          : edit[k]
      )
    );
    setState((prev) => ({
      ...prev,
      edit: prev.original.map((e, k) =>
        e.includes(label)
          ? value === ""
            ? label
            : e.replace(label, value)
          : prev.edit[k]
      ),
      arrayE: prev.arrayE.map((e, k) =>
        k === key ? (value === "" ? label : value) : e
      )
    }));
  };

  console.log(state);

  return (
    <div className="App">
      <div style={{ flex: 1 }}>
        <div style={{}}>
          <input type="file" onChange={(e) => showFile(e)} />
          {arrayO.map((label, key) => (
            <div key={key} style={{ paddingTop: 5 }}>
              <TextField
                id="outlined-basic"
                label={label}
                variant="outlined"
                size={"small"}
                onChange={({ target: { value } }) =>
                  onChange(value, label, key)
                }
              />
            </div>
          ))}
        </div>
        <div>
          {edit.map((el, key) => (
            <div key={key}>{el}</div>
          ))}
        </div>
      </div>
      <div style={{ flex: 1, backgroundColor: "#4287f5" }}>
        {arrayO.map((el, key) => (
          <div key={key}>{el}</div>
        ))}
      </div>
      <div style={{ flex: 1, backgroundColor: "#f5cb42" }}>
        {arrayE.map((el, key) => (
          <div key={key}>{el}</div>
        ))}
      </div>
    </div>
  );
}

解决方案

我已经更改了showfile函数,以使用文件读取器的结果将其提供给PizZip实例:

const showFile = async (e) => {
  console.log('showfile', e)
  e.preventDefault();
  const reader = new FileReader();
  reader.onload = async (e) => {
    const content = e.target.result;
    var doc = new Docxtemplater(new PizZip(content), {delimiters: {start: '12op1j2po1j2poj1po', end: 'op21j4po21jp4oj1op24j'}});
    var text = doc.getFullText();
    console.log(text)
  };
  reader.readAsBinaryString(e.target.files[0]);
};

请注意,我为开始和结束分隔符放置了一些随机字符串,以避免将文档解析为模板。

相关文章