You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用react-data-export一键下载多份Excel并压缩为ZIP?

解决方案:react-data-export实现多Excel文件打包ZIP下载

react-data-export本身不支持多文件打包导出,我们可以结合它底层依赖的xlsx库,加上jszip来实现ZIP打包功能,以下是具体实现步骤:

步骤1:安装依赖

首先安装jszip(用于ZIP打包),如果项目未安装xlsx也需要补充安装:

npm install jszip xlsx --save

步骤2:修改组件代码

替换原有单文件导出逻辑,改为生成多份Excel Blob后打包ZIP下载:

import React, { useState, useEffect } from 'react';
import { Container, Col, Row, Button, Modal, Tooltip } from 'react-bootstrap';
import ReactExport from 'react-data-export';
import JSZip from 'jszip';
import * as XLSX from 'xlsx';

const ExcelFile = ReactExport.ExcelFile;
const ExcelSheet = ReactExport.ExcelFile.ExcelSheet;
const ExcelColumn = ReactExport.ExcelFile.ExcelColumn;

const VesselReportExcelGenerator = (props) => {
    const [exportModalOpen, setExportModalOpen] = useState(false);
    const [excelDataList, setExcelDataList] = useState([]); // 存储多份导出数据集
    const vesselReportApi = new VesselReportApi();
    const loggedInVesselName = JSON.parse(localStorage.getItem('selectedVessel'))?.name;

    useEffect(() => {
        fetchMultipleVesselReports();
    }, []);

    // 获取多份需要导出的数据(示例:日报、维护报)
    const fetchMultipleVesselReports = async () => {
        try {
            const dailyLogData = await vesselReportApi.getVesselReportFormStructure();
            const maintenanceLogData = await vesselReportApi.getVesselMaintenanceReport(); // 假设存在该接口
            setExcelDataList([
                { name: 'Daily Log', columns: columns, data: dailyLogData },
                { name: 'Maintenance Log', columns: maintenanceColumns, data: maintenanceLogData } // 对应维护报表的列配置
            ]);
        } catch (error) {
            console.log(error);
            props.setMessages([{type : "danger", message : 'Something went wrong. Please try again!'}]);
        }
    };

    // 生成单个Excel文件的Blob对象
    const generateExcelBlob = (sheetName, columns, data) => {
        const dataSet = [{ columns, data }];
        const excelFile = new ExcelFile({ filename: sheetName });
        excelFile.addSheet(new ExcelSheet({ name: sheetName, dataSet }));
        const wb = excelFile.generate();
        return XLSX.write(wb, { type: 'blob', bookType: 'xlsx' });
    };

    // 打包所有Excel为ZIP并触发下载
    const handleExportZip = async () => {
        const zip = new JSZip();
        // 遍历数据集生成每个Excel文件并加入ZIP
        for (const item of excelDataList) {
            const blob = await generateExcelBlob(item.name, item.columns, item.data);
            zip.file(`${loggedInVesselName}_${item.name}Template.xlsx`, blob);
        }
        // 生成ZIP并下载
        zip.generateAsync({ type: 'blob' }).then((content) => {
            const url = URL.createObjectURL(content);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${loggedInVesselName}_AllReports.zip`;
            a.click();
            URL.revokeObjectURL(url);
            setExportModalOpen(false);
        }).catch(error => {
            console.error('打包ZIP失败:', error);
            props.setMessages([{type : "danger", message : 'Failed to generate ZIP file. Please try again!'}]);
        });
    };

    return (
        <Container fluid className="VesselReportExcelBackground">
            <Col lg={7}>
                <Row style={{ justifyContent: 'center', height: '2rem', paddingTop: "40px", height: "10%" }}>
                    <div style={{ fontSize: "2rem", color: config.KSTColors.MAIN, fontWeight: "900" }}>
                        OFFLINE VESSEL REPORT
                    </div>
                </Row>
                {/* Export Vessel report excel UI */}
                <Row xs={12} md={3} style={{ backgroundColor: config.KSTColors.CARD_BG, height: "150px", borderRadius: "15px", marginTop: "40px" }}>
                    <Col xs={3} lg={3} style={{ padding: "0px" }}>
                        <Button className="VesselReportExcelEditButton" style={{ backgroundColor: config.KSTColors.MAIN, borderColor: config.KSTColors.MAIN, width: "100%" }} onClick={() => setExportModalOpen(true)}>
                            <img src={VesselExportIMG} alt="Excel Export" style={{ height: "120px" }}/>
                        </Button>
                    </Col>
                    <Col xs={6} lg={6}>
                        <div style={{ display: "flex", width: "100%", height: "100%", flexDirection: "column", justifyContent: "center" }}>
                            <div style={{ marginTop: "5px", width: "100%", height: "50%", color: config.KSTColors.MAIN, fontSize: "32px",
                                display: "flex", justifyContent: "center", alignItems: "center" }}>
                                Download Template
                            </div>
                        </div>
                    </Col>
                </Row>
            </Col>
            <Modal size="lg" show={exportModalOpen} onHide={() => setExportModalOpen(false)} aria-labelledby="VRTemplateDownload" centered>
                <Modal.Header style={{ backgroundColor: '#e6e6e6' }}>
                    <Modal.Title id="VRTemplateDownload">Export Vessel Report Template</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <span style={{ fontSize: "12px" }}>Are you sure to generate all {loggedInVesselName} vessel reports?</span>
                </Modal.Body>
                <Modal.Footer style={{ color: '#04588e' }}>
                    <Button onClick={() => setExportModalOpen(false)} style={{ backgroundColor: 'white', color: '#04588e', paddingTop: '2px', paddingBottom: '2px', paddingLeft: '20px', paddingRight: '20px' }}>Cancel</Button>
                    {/* 替换原有单文件按钮为ZIP导出按钮 */}
                    <Tooltip title="Export All Reports as ZIP" placement="bottom">
                        <Button style={{ backgroundColor: '#04588e', color: 'white', paddingTop: '2px', paddingBottom: '2px', paddingLeft: '20px', paddingRight: '20px' }} onClick={handleExportZip}>
                            All Reports (ZIP)
                        </Button>
                    </Tooltip>
                </Modal.Footer>
            </Modal>
        </Container>
    );
};

export default withMessageManager(VesselReportExcelGenerator);

关键说明

  • 多数据管理:excelDataList存储所有需要导出的数据集,每个集合包含文件名、列配置和对应数据,可根据实际业务调整数据源。
  • Excel Blob生成:复用react-data-export的工作簿生成逻辑,通过xlsx将工作簿转为Blob格式,确保导出文件格式与原有单文件一致。
  • ZIP打包逻辑:使用jszip遍历所有Blob文件,添加到ZIP包后生成浏览器可下载的链接,完成一键打包下载。
  • 错误处理:在打包过程中加入异常捕获,避免前端崩溃并给用户提示。

内容的提问来源于stack exchange,提问作者harizh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:34:57