Excel 文件转换为 html 表格然后设置为可编辑,但转换回 excel 文件时不会反映更改

问题描述 投票:0回答:1

我正在使用 React 并使用 useState 来处理变量。我还有 xlsx (SheetJS) 作为依赖项。

import React, { useState } from 'react';
import * as XLSX from 'xlsx';

export default function ExcelImport() {

    const tnStyles = {
        border: '1px solid black',
        padding: '5px',
        backgroundColor: 'white',
        textAlign: 'center',
        verticalAlign: 'top',
        whiteSpace: 'pre-wrap'
    };

    const [htmlData, setHtmlData] = useState('');

    const convertExcelToHTML = (file) => {
        const reader = new FileReader();
        reader.onload = (e) => {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });
            const firstSheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[firstSheetName];
            const html = XLSX.utils.sheet_to_html(worksheet);
            setHtmlData(html);
        };
        reader.readAsArrayBuffer(file);
    };

    const handleFileChange = (e) => {
        const file = e.target.files[0];
        if (file) {
            convertExcelToHTML(file);
        }
    };

    const exportToFile = (htmlData) => {
        //export
        const ws = XLSX.utils.table_to_sheet(document.getElementById('base-table'));
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, 'Report');
        XLSX.writeFile(wb, 'report.xlsx');
    };

    const handleHtmlChange = (e) => {
        const editedHtml = e.target.innerHTML;
        setHtmlData(editedHtml);
    };

    return (
        <div>
            <div>
                <input type="file" accept=".xls, .xlsx" onChange={handleFileChange} />
                <div
                    id="base-table"
                    style={tnStyles}
                    contentEditable={true}
                    dangerouslySetInnerHTML={{ __html: htmlData }}
                    onInput={handleHtmlChange}
                />
            </div>
            <div>
                <button style={tnStyles} onClick={() => exportToFile(htmlData)}>Export Edited HTML Content to Excel</button>
            </div>
        </div>
    );
}

期望的行为: 用户上传 Excel 文件 ---> 文件转换为 html 表格 ---> 以 contentEditable={true} 显示表格 ---> 用户编辑表格 ---> 保存更改 --- > 用户将更新的 html 表导出为 excel

当前行为: 用户上传 Excel 文件 ---> 文件转换为 html 表格 ---> 以 contentEditable={true} 显示表格 ---> 用户编辑表格 ---> 保存更改 --- > 用户导出 html 表格的原始未修改版本

计划创建一个网站,接收 Excel 文件作为输入,然后将所述 Excel 文件转换为 html 表格,然后在网站中显示它们,同时可编辑(仅限文本)。预期的结果是拥有一个包含可编辑内容的表格,然后可以将其转换回 Excel 文件,然后导出。

我正在使用免费版本的 SheetJS。

我尝试将更改存储在不同的变量(editedHtml)中,并使用它自己的useState,然后保留原始内容,而仅导出更改后的html表。

我尝试使用控制台日志来查看 htmlData 和editedHtml 的内容。两者都反映了所做的更改,但导出其中任何一个时,这些更改都不会应用,并且我留下的是上传到网站的相同 Excel 表格。

reactjs html-table export-to-excel sheetjs
1个回答
0
投票

生成的 html 表将每个单元格的实际值存储在名为“data-v”的属性中。在此代码中,''内的文本可以更改和更新并保存到“htmlData”中,之所以没有反映在导出的excel中是因为xlsx使用'data-v'的值作为单元格的值,并且不是其 '' 的内容。

我做了什么来解决这个问题:

  1. 解析 '' 元素内的值并将它们作为键值对存储在数组中 [id: text, id text, id: text...]。
  2. 用解析后的值替换“data-v”的值。我使用特定的 '' id 来查找哪个值在哪里。保存在变量“editedData”中。
  3. 将“editedData”设置为“htmlData”的值,然后导出为 xlsx 文件。
© www.soinside.com 2019 - 2024. All rights reserved.