npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

acc-file-edit-react

v1.0.3

Published

React 文档编辑组件,基于 OnlyOffice API 与 x2t 转换能力。

Readme

file-edit

基于 React、OnlyOffice API 和 x2t 的前端文档编辑组件。

适用于浏览器端文档预览、编辑、保存和导出场景,支持以 npm 包形式直接集成到业务项目中。

功能特性

  • 纯前端文档编辑,无需后端参与编辑流程
  • 支持常见文档类型:docdocxodtrtftxtxlsxlsxodscsvpptpptxodp
  • 打开 .doc 文件时,会自动按 .docx 进入编辑和保存流程
  • 支持 onSave 回调,拿到保存后的二进制数据
  • 支持 onContentChange 回调,监听编辑内容变化
  • 支持通过 ref.save() 主动触发保存
  • npm 包已内置运行所需静态资源,默认可直接使用

安装

npm install file-edit

本包将 react 作为 peerDependencies,请确保宿主项目已安装 React 18 或兼容版本。

最小使用示例

import React, { useState } from "react";
import DocumentEditor from "file-edit";

export default function Demo() {
  const [file, setFile] = useState<File | null>(null);

  return (
    <div style={{ height: "100vh" }}>
      <input
        type="file"
        onChange={(event) => {
          setFile(event.target.files?.[0] ?? null);
        }}
      />

      {file ? (
        <DocumentEditor
          file={{
            fileName: file.name,
            file,
          }}
        />
      ) : null}
    </div>
  );
}

创建新文档

file.filenull 时,组件会根据 fileName 后缀创建一个空白文档。

import React from "react";
import DocumentEditor from "file-edit";

export default function CreateDocDemo() {
  return (
    <DocumentEditor
      file={{
        fileName: "新建文档.docx",
        file: null,
      }}
    />
  );
}

保存回调示例

通过 onSave 可以直接拿到保存后的二进制内容和文件名,适合自己上传到服务端或做二次处理。

import React from "react";
import DocumentEditor from "file-edit";

export default function SaveCallbackDemo() {
  return (
    <DocumentEditor
      file={{
        fileName: "合同.docx",
        file: selectedFile,
      }}
      onSave={({ bin, fileName }) => {
        console.log("保存文件名:", fileName);
        console.log("二进制大小:", bin.byteLength);
      }}
    />
  );
}

如果保存是由编辑器内置保存按钮触发:

  • 会先触发 onSave
  • 如果当前不是通过 ref.save() 发起的保存,组件仍会继续执行浏览器下载

监听内容变化

import React from "react";
import DocumentEditor from "file-edit";

export default function ContentChangeDemo() {
  return (
    <DocumentEditor
      file={{
        fileName: "内容变化示例.docx",
        file: selectedFile,
      }}
      onContentChange={() => {
        console.log("文档内容发生变化");
      }}
    />
  );
}

通过 ref 主动保存

import React, { useRef } from "react";
import DocumentEditor, { type DocumentEditorRef } from "file-edit";

export default function RefSaveDemo() {
  const editorRef = useRef<DocumentEditorRef>(null);

  const handleSave = async () => {
    const result = await editorRef.current?.save();

    if (!result) {
      console.log("编辑器尚未初始化完成");
      return;
    }

    console.log(result.fileName);
    console.log(result.bin);
  };

  return (
    <>
      <button onClick={handleSave}>主动保存</button>
      <DocumentEditor
        ref={editorRef}
        file={{
          fileName: "手动保存示例.docx",
          file: selectedFile,
        }}
      />
    </>
  );
}

ref.save() 的行为说明:

  • 返回值类型:Promise<{ bin: Uint8Array; fileName: string } | null>
  • 编辑器尚未初始化时返回 null
  • 通过 ref.save() 触发保存时,不会额外触发浏览器下载
  • 默认导出格式:
    • 文档类导出为 docx
    • 表格类导出为 xlsx
    • 演示类导出为 pptx

.doc 自动转 .docx

如果传入的是 .doc 文件:

  • 打开时会自动按 .docx 进入编辑流程
  • 保存时文件名会自动变成 .docx
  • onSaveref.save() 返回的 fileName 也是 .docx

示例:

<DocumentEditor
  file={{
    fileName: "旧版文档.doc",
    file: selectedFile,
  }}
/>

保存后得到的文件名类似:

旧版文档.docx

资源加载说明

本包默认会从当前 npm 包版本对应的 unpkg 地址加载静态资源,因此在公开 npm 场景下通常可以直接使用。

之所以默认使用 unpkg,是因为当前内置的 x2t.wasm 文件较大,使用 jsDelivr 时可能会因为文件大小限制导致访问失败。

默认资源基路径可以通过以下方法获取:

import { getDefaultAssetBaseUrl } from "file-edit";

console.log(getDefaultAssetBaseUrl());

自定义静态资源地址

如果你的环境无法访问外网 CDN,或者你想将静态资源托管到自己的服务器,可以通过 assetBaseUrl 指定资源基础路径。

目录结构要求如下:

你的静态资源目录/
  web-apps/
    apps/
      api/
        documents/
          api.js
  wasm/
    x2t/
      x2t.js
      x2t.wasm

使用方式:

import React from "react";
import DocumentEditor from "file-edit";

export default function PrivateAssetDemo() {
  return (
    <DocumentEditor
      assetBaseUrl="https://your-static.example.com/file-edit-assets"
      file={{
        fileName: "私有资源示例.docx",
        file: selectedFile,
      }}
    />
  );
}

此时组件会自动去加载:

  • https://your-static.example.com/file-edit-assets/web-apps/apps/api/documents/api.js
  • https://your-static.example.com/file-edit-assets/wasm/x2t/x2t.js

类型定义

DocumentType

interface DocumentType {
  fileName: string;
  file: File | null;
}

DocumentEditorSaveData

interface DocumentEditorSaveData {
  bin: Uint8Array;
  fileName: string;
}

DocumentEditorProps

interface DocumentEditorProps {
  file: DocumentType;
  assetBaseUrl?: string;
  onSave?: (data: DocumentEditorSaveData) => void;
  onContentChange?: () => void;
}

DocumentEditorRef

interface DocumentEditorRef {
  save: () => Promise<DocumentEditorSaveData | null>;
}

使用建议

  • 组件容器建议显式设置高度,否则编辑区域可能不可见
  • 建议在业务侧保存一份当前 File 的原始文件名,用于展示和版本管理
  • 如果你使用的是私有 npm 或离线环境,建议配合 assetBaseUrl 使用
  • 如果需要将保存后的内容上传到后端,优先使用 onSaveref.save()

发布构建

本地构建:

npm run build

发布前构建会自动执行:

npm publish

当前包构建后会生成:

  • dist/index.js
  • dist/index.mjs
  • dist/index.d.ts
  • dist/assets/web-apps
  • dist/assets/wasm

注意事项

  • 当前 package.json 中的包名示例为 file-edit,正式发布前请根据实际情况调整
  • 默认 unpkg 方案依赖包已成功发布到公开 npm
  • 浏览器保存能力依赖前端环境本身,不依赖后端接口