【问题标题】:Add multiple worksheet to a stream workbook with ExcelJS使用 ExcelJS 将多个工作表添加到流工作簿
【发布时间】:2019-01-17 09:24:18
【问题描述】:

上下文

  • NodeJS 10
  • ExcelJS 0.8.5
  • LibreOffice 5.1.6.2 在 Ubuntu 上

问题

我正在尝试使用ExcelJS 创建一个多页 Excel 文件。 我正在关注ExcelJS github page的官方文档。

第一步是创建工作簿。就我而言,我想要一个流,因为我会附加很多数据。

// Create Excel Workbook Stream
const workbookStream = new Excel.stream.xlsx.WorkbookWriter({
  filename: path,
  useStyles: true,
  useSharedStrings: true,
});

然后我将工作表添加到创建的工作簿的流中,如文档 Worksheet Properties 中所述。

const sheet = workbookStream.addSheet('sheet1'); // Throw here

但是这样,我得到了以下错误:

'类型错误:workbookStream.addSheet 不是函数


我还发现了一个不会抛出但不起作用并且不会创建很多工作表的代码。

const header = ['A', 'B', 'C'];

const sheet1 = Excel.addSheetOnWorkbook({
  workbook: workbookStream,
  name: 'sheet1',
});

const sheet2 = Excel.addSheetOnWorkbook({
  workbook: workbookStream,
  name: 'sheet2',
});

sheet.addRow(header).commit();

sheet.addRow(header).commit();

await workbookStream.commit();

在这种情况下,仅创建 sheet1(使用 LibreOffice 5.1.6.2 打开)。

有什么方法可以用ExcelJS 解决这个问题?

【问题讨论】:

    标签: node.js exceljs


    【解决方案1】:

    我不知道这对你有多大帮助,但在我的环境中:

    • Windows 10 (10.0.17134.0)
    • 节点 10.15.0
    • exceljs 1.6.0

    worksheet.state 设置为visible 后,我可以在LibreOffice 中看到它:

    const Excel = require('exceljs');
    const workbook = new Excel.Workbook();
    const fs = require('fs');
    const filename = "test.xlsx";
    const sheetNames = ["A", "B", "C", "D"];
    
    sheetNames.forEach(sheetName => {
        let worksheet = workbook.addWorksheet(sheetName);
        // I believe this needs to be set to show in LibreOffice.
        worksheet.state = 'visible';
    });
    
    const stream = fs.createWriteStream(filename);
    workbook.xlsx.write(stream)
    .then(function() {
        console.log(`File: ${filename} saved!`);
        stream.end();
    }).catch(error => {
        console.err(`File: ${filename} save failed: `, error);
    });
    

    使用流式 XLSX WorkbookWriter

    const Excel = require('exceljs');
    const sheetNames = ["A", "B", "C", "D"];
    
    const workbook = new Excel.stream.xlsx.WorkbookWriter( { filename: './streamed-workbook.xlsx' } );
    
    sheetNames.forEach(sheetName => {
        let worksheet = workbook.addWorksheet(sheetName);
        worksheet.state = 'visible';
        worksheet.commit();
    });
    
    // Finished the workbook.
    workbook.commit()
    .then(function() {
        console.log(`Worksheet committed!`);
    });
    

    我也会在 Ubuntu 机器上进行测试。

    XSLX 文件只是包含多个 .xml 文件的 .zip 文件,因此您可以自己检查 XML 数据。

    显示 LibreOffice 与 exceljs 生成的原始 Xml (worksheet.xml):

    LibreOffice

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
        <fileVersion appName="Calc"/>
        <workbookPr backupFile="false" showObjects="all" date1904="false"/>
        <workbookProtection/>
        <bookViews>
            <workbookView showHorizontalScroll="true" showVerticalScroll="true" showSheetTabs="true" xWindow="0" yWindow="0" windowWidth="16384" windowHeight="8192" tabRatio="500" firstSheet="0" activeTab="1"/>
        </bookViews>
        <sheets>
            <sheet name="A" sheetId="1" state="visible" r:id="rId2"/>
            <sheet name="B" sheetId="2" state="visible" r:id="rId3"/>
        </sheets>
        <calcPr iterateCount="100" refMode="A1" iterate="false" iterateDelta="0.001"/>
        <extLst>
            <ext xmlns:loext="http://schemas.libreoffice.org/" uri="{7626C862-2A13-11E5-B345-FEFF819CDC9F}">
                <loext:extCalcPr stringRefSyntax="CalcA1"/>
            </ext>
        </extLst>
    </workbook>
    
    

    exceljs

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
        <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303"/>
        <workbookPr defaultThemeVersion="164011" filterPrivacy="1"/>
        <sheets>
            <sheet sheetId="1" name="A" state="show" r:id="rId3"/>
            <sheet sheetId="2" name="B" state="show" r:id="rId4"/>
            <sheet sheetId="3" name="C" state="show" r:id="rId5"/>
            <sheet sheetId="4" name="D" state="show" r:id="rId6"/>
        </sheets>
        <calcPr calcId="171027"/>
    </workbook>
    

    还有一件事

    当设置了一些非字母数字字符时,工作表标题可能损坏 XML文件结构。

    注意工作表标题!

    【讨论】:

    • 您在 Windows 10 上运行,所以我想您正在使用 Microsoft Office Excel 打开结果文件?它可能会导致不同的行为。
    • @Alrick,我都试过了,我得到了一个有趣的结果。工作表在 Excel 中正确显示,但在 LibreOffice 中只有工作表 A 显示。当我解压 .xlsx 文件时,我可以在 worksheets 目录中看到确实有 4 个工作表……奇怪!
    • 好的,我很高兴你能轻而易举地解决这个问题
    • 所以我认为数据在那里.. 只是由于某种原因它没有显示在 Libre Office 中.. 可能对数据的格式存在一些分歧。同样在 LibreOffice 的最左下角,它显示“Sheet 1 of 4”,所以它工作了一半......
    • 我将状态更改为可见,因为这是我在 LibreOffice 中创建具有多个工作表的新工作簿时 Xml 显示的内容。无论如何,解决方法都会对我的环境产生影响!
    猜你喜欢
    • 2017-12-21
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多