爱意满满的作品展示区。
demomacro

最近做了一个支持 docx,pptx,xlsx 的生成、解析、模板填充的纯 Typescript 库

  •  
  •   demomacro ·
    DemoMacro · Jun 18 · 1349 views
    This topic created in 34 days ago, the information mentioned may be changed or developed.

    因为日常需求,需要将 docx 存储解析为 JSON 格式方便后续处理,并且能进行简单地在线编辑、集成 AI 工具,一开始是写了 Docen 这个库,将 docx 转为了 Tiptap JSON 格式,简单写了一些解析以支持 tiptap 或者说 html 支持的样式,再通过 dolanmiu/docx 这个包进行导出,但是后期随着需要用到的功能越来越多,感觉不管是解析还是生成的方式都越发显得局限,所以另外做了这个库 Office Open

    第一阶段,我先是基于原版 docx 包进行了完善,加入了关于 Chart 、Smartart 、SDT 控件等功能,支持了绝大部分的 wml/pml/sml 元素,默认设置更贴近于 Microsoft Office/WPS Office 的标准,重写了关于 xml 的生成和解析部分,将原本的打包从 jszip 替换为了 fflate ,针对 node 环境使用了 zlib 来实现,以此支持了 docx,pptx,xlsx 的生成。

    第二阶段,因为原版是基于 Class 实现的,且中间路径过长,我逐步迁移到了通过字符串拼接的方式用以提高性能,但这个过程中依然遇到了问题,因为我的根本需求是需要通过 JSON 生成和解析,大量的 Class 和 JSON 模式混杂使得维护起来越发困难

    第三阶段,我全部剔除了所有 Class 的部分,完全转换为通过 JSON 来生成 docx,pptx,xlsx 文件,并且增加了大量 round-trip 的测试来保持生成和解析的一致性,目前与同类产品( docx,pptxgenjs,hucre )进行对比后,单独针对生成的部分进行了 Benchmark 测试,还是有比较明显的优势的。

    Large Docx (~100MB) — Mixed Content

    500 styled paragraphs + 38 mixed-size images (1-5MB, 100MB total) + 50x10 table.

    Scenario Default sync Default async All STORE sync All STORE async docx
    Mixed (500p+38img+50x10) 9.7 ops/s 8.2 ops/s 5.1 ops/s 4.2 ops/s 0.30 ops/s

    Large Pptx (~100MB) — Mixed Content

    40 slides x (2 shapes + 2 mixed-size images + 3x3 table).

    Scenario Default sync Default async All STORE sync All STORE async PptxGenJS DEFLATE PptxGenJS STORE
    40 slides mixed 227 ops/s 124 ops/s 708 ops/s 721 ops/s 0.23 ops/s 0.22 ops/s

    Large Xlsx — 100,000 rows × 20 columns (2M cells)

    Scenario Default sync Default async All STORE sync All STORE async hucre
    100k × 20 0.87 ops/s 0.81 ops/s 1.02 ops/s 0.96 ops/s 0.39 ops/s

    现在其实我觉得可能陷入了一些瓶颈,比如说让 AI 通过工具输入 JSON 生成对应的文档,因为没有实现完整的 zod 校验,导致错了的话 AI 也没法很好第一时间发现错误,即便是支持通过 MCP 查询文档也经常会遇到一些错误。

    当前其实是支持类似如下 JSON 直接去生成一个完整的 docx 文件,可以通过 Office Open Website 这个网站去在线体验

    {
        "sections": [
            {
                "children": [
                    { "paragraph": { "children": [{ "text": "Hello, World!", "bold": true }] } }
                ]
            }
        ]
    }
    

    想征询一下大家的意见,是否应该将类型定义转化为 zod ,以便更好的类型校验,或者生成对应的 JSON Schema ,以及对于当前的类型定义方式是否有更合理的建议

    因为后期我是准备在基于Office Open库的基础上实现在线编辑和预览,所以后面会逐步将 Docen 包的解析层替换为当前实现,对于这个的实现我还在尝试,是通过 Tiptap JSON 的形式还是别的什么,以及当前基于 Tiptap 的分页和渲染方案可能都需要另外考虑,我在想是否需要基于 Leaferjs 进行高性能渲染,这会影响后期的维护思路,所以希望和大家有所讨论,能够提供参考意见,感谢~

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3326 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 11:18 · PVG 19:18 · LAX 04:18 · JFK 07:18
    ♥ Do have faith in what you're doing.