【问题标题】:Create copies of template XLSM file using NodeJS?使用 NodeJS 创建模板 XLSM 文件的副本?
【发布时间】:2021-10-20 23:16:28
【问题描述】:

我有一个节点项目,我需要节点以使用现有 XLSM 文件作为模板来创建新的 XLSM 文件。该模板包含大量样式、图像和 VBA。应用程序只需将值插入到几个单元格中,并以谨慎的名称保存新文件。

我已尝试使用 XLSX 和 ExcelJS npms 来完成此任务。两者都以不同的方式失败:

ExcelJS:目前似乎不支持编写 XLSM 文件。尝试这样做会导致文件损坏。

XLSX:我无法创建模板的真实副本。除其他外,它缺少格式和 VBA。这是我开始使用的非常基本的代码:

                const templatePath = "C:/Users/rapsputinforever/Desktop/template.xlsm"
                const directory = "C:/Users/rapsputinforever/Desktop"
                
                const workbook = XLSX.readFile(templatePath);
                
                // will insert data to some cells here

                XLSX.writeFile(workbook, directory + '/copy.xlsm');

我知道这个包有很多选项,这些选项似乎与我遇到的问题无关,并且有助于完成表面上看起来非常简单的任务:

  1. 阅读模板
  2. 向单元格添加值
  3. 写为新文件保留所有 VBA、样式等

我愿意研究其他包、库,甚至其他技术。这个工具是 React 应用程序后端的一部分,但是我不确定 React 是否可以完成这个。我愿意接受任何建议。感谢您的帮助!

【问题讨论】:

  • 我一直在考虑的当前解决方案是使用“fs”npm 和 excel VBA 执行“变通办法”,产生相同的结果。用户单击 React Node 中的“发送到模板”按钮使用 fs 复制模板 XLSM(希望保持文件的完整性) 节点使用所需数据创建 CSV,保存在本地驱动器中 用户在下载时获取重复文件 用户打开文件,单击“导入”按钮,触发 VBA 查找和使用创建的 CSV 用户继续使用 Clunky 设计的模板,但使用 Excel 也是如此,所以按部就班?

标签: node.js reactjs exceljs xlsm sheetjs


【解决方案1】:

我通过将问题分解为其组成部分成功地解决了问题。了解 excel 文件的性质,它们是 XML 文件的压缩包(来源 here),然后逐步执行以下步骤:

  1. 创建模板 XLSM 文件的副本,副本具有“.zip”作为扩展名 ('fs')
  2. 解压缩 zip 文件('extract-zip')
  3. 读取 sharedStrings.XML ('fs')
  4. 统计sharedStrings中XML标签“”的迭代次数

例子:

let stringCount = (sharedStrings.match(/<si>/g) || []).length;
  1. 读取 worksheet1.XML(或任何要插入的工作表数据)
  2. 通过查找单元格的标签来定位单元格。如果为空,标签将如下所示:

例子:

<c r="D10" s="29"/>

注意,r = 单元格地址,s = 样式标签,你要在下一步中维护这两者...

  1. 将空单元格标记替换为共享字符串标志和要插入的新字符串的所需索引。

例子:

<c r="D9" s="29" t="s"><v>${stringCount}</v></c>

总结到目前为止,我们将单元格 XML 标记替换为插入字符串,该字符串插入到 sharedStrings 文件中并由该新字符串的索引/计数引用。这可以在循环中插入以插入要插入的值数组。

  1. 同时保存 sharedFiles.XML 和 worksheet1.XML ('fs')
  2. 将解压后的文件夹打包成一个新的存档('archiver')
  3. 用“.XLSM”扩展名(“fs”)重命名存档文件夹
  4. 清理,终止所有重复的 zip 文件/文件夹

如果工作正确,sharedString 索引是准确的,如果样式 ID 保持不变,并且所有这些异步操作都应用了正确的脚本结构,则生成的文件应该具有所需的结果,因为包含的完整性VBA、样式、查询、图像等都是通过创建一个真实的副本并操纵该副本的组成部分来维护的。

我是一名新手开发人员,毫无疑问,我的方法过于冗长且效率低下,而且我对与其他库相比为何有效的理解并不仅仅取决于我的直觉。我认为问题在于 ExcelJS 和其他 NPM 在“缓冲区”中创建了一个工作表,不幸的是,该工作表仅包含该库基于 XLSX 文件说明的原始文件的任何元素。如果 ExcelJS 不查看 VBA,那么新工作表将没有 VBA,因为当该工作表在缓冲区中复制时,它只会复制其范围内的任何内容。

我仍然非常愿意接受更多建议/替代方案/方法/智慧。我希望进一步微调它以使其具有可扩展性:我只能为我非常具体的应用程序设计它。如果我设法概括这一点并清理我的代码,我将在这里分享 sn-p。

谢谢,

编辑:你好!事实证明,事情并非如此简单!尽管在打开文件时没有提示错误,但副本仍然存在一些背景问题,如果您碰巧使用 Power Query 来解析上述 XLSM 文件,这些问题就会很明显。此外,任何引用节点解决方案填充的单元格的公式都不会在打开文件时更新。要解决此问题,请运行此 VBA:

Application.CalculateFullRebuild

这将更新每张纸上的所有公式。保存此文件后,工作表应再次“正常”。手头的问题基于 XML 文件 calcChain.XML

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    相关资源
    最近更新 更多