Skip to content

Feishu Docx

Feishu Docx 是一个可以支持将飞书 Docx 文档格式转换为其他任意格式的实现。

这是一个独立的 NPM 库,你可以自由引入到自己的前端项目中使用。feishu-pages 工具内部是采用 feishu-docx 来实现内容的转换,此文档仅介绍 feishu-docx 导出后的文档格式细节。

目前支持格式:

  • Markdown (GFM)

Installation

💡

如果使用 feishu-pages 可以跳过安装和使用部分,feishu-pages 内部已经集成了。

bash
yarn add feishu-docx

Usage

ts
import { MarkdownRenderer } from 'feishu-docx'

// Load docx JSON from file
const docx = fs.readFileSync('test.json')
const render = new MarkdownRenderer(docx)
const text = render.parse();
const imageTokens = render.imageTokens;

支持飞书 Block 类型

详见:支持的内容格式

Markdown GFM

绝大多数的内容文档输出均会以 Markdown GFM 的格式输出,基本上兼容性可以达到 99% 还原。

特殊 HTML

你可能会看到最终输出的 Markdown 里面实际上还混杂着部分的 HTML 代码。这是由于飞书的一些特殊文档格式(比如:Callout),使得我们必须在 Markdown 里面加入一些自定义 HTML + 自行实现 CSS 来达到相应的排版效果。

不用担心,绝大多数的 Markdown 工具均支持 Markdown 与 HTML 混合排版,如你当前使用的工具无法支持,请注意检查他们的 HTML 开关。

因为外面是HTML,所以里面的所有内容也输出为HTML,否则Markdown无法正确识别。

Image

原本 Markdown 是支持图片的,但在飞书文档的里面我们有尺寸调整,图片对齐方式等更详细的细节。

由于目前飞书 API 并未给出调整过后的图片缩放尺寸,因此我们无法还原在飞书文档里面调整后的尺寸。建议在文档上设定图片宽度 100% 来使用。 此问题已经返回给飞书 API 团队,需要等待他们改进。

图片导出的 Markdown 代码可能是这样的:

md
<img src="M9hDb8WXzo7TU5xg4xtcvArPnxe" src-width="410" src-height="404" align="center"/>
  • src-widthsrc-height - 为原始图片的 width, height
  • align - 为原始文档内的文档对齐方式,[left, center, right]

Callout

Callout 是飞书文档上用来标识一些重点内容的。

例如,这个样式:

🐸

This block is a Callout with green color.

导出后生成的内容 HTML 为:

md
<div class="callout callout-bg-3 callout-border-3">
🐸 This block is a Callout with green color.
</div>

其中 callout-bg-3callout-border-3 分别表示了背景色与边框色,3 是绿色,数字范围是 1-17,分别表示了不同的颜色。

颜色对应表,详见飞书文档:CalloutBackgroundColor, CalloutBorderColor

建议参考 CSS (注意这里用了 Tailwind CSS):

scss
.callout {
  padding: 0.5em 1em;
  margin: 1.5em 0;
  border: 2px solid #ccc;
  border-radius: 5px;
  font-size: 1em;

  &-bg-1,
  &-bg-8 {
    @apply bg-red-50 dark:bg-red-950;
  }
  &-bg-2,
  &-bg-9 {
    @apply bg-orange-50 dark:bg-orange-950;
  }
  &-bg-3,
  &-bg-10 {
    @apply bg-yellow-50 dark:bg-yellow-950;
  }
  &-bg-4,
  &-bg-11 {
    @apply bg-green-50 dark:bg-green-950;
  }
  &-bg-5,
  &-bg-12 {
    @apply bg-blue-50 dark:bg-blue-950;
  }
  &-bg-6,
  &-bg-13 {
    @apply bg-purple-50 dark:bg-purple-950;
  }
  &-bg-7,
  &-bg-14 {
    @apply bg-gray-50 dark:bg-gray-950;
  }

  &-border-1,
  &-border-8 {
    @apply border-red-200 dark:border-red-800;
  }
  &-border-2,
  &-border-9 {
    @apply border-orange-200 dark:border-orange-800;
  }
  &-border-3,
  &-border-10 {
    @apply border-yellow-200 dark:border-yellow-800;
  }
  &-border-4,
  &-border-11 {
    @apply border-green-200 dark:border-green-800;
  }
  &-border-5,
  &-border-12 {
    @apply border-blue-200 dark:border-blue-800;
  }
  &-border-6,
  &-border-13 {
    @apply border-purple-200 dark:border-purple-800;
  }
  &-border-7,
  &-border-14 {
    @apply border-gray-200 dark:border-gray-800;
  }

  @apply text-gray-800 dark:text-gray-200;
}

Grid

Grid 在飞书文档里面使用来实现垂直分栏布局的,这种我们无法用 Markdown 来还原,而实际文档撰写中其实还挺常用的,例如我们可能会用 Grid 来一行排列 3 张图片。

上面的结构生成后 HTML 是这样:

md
<div class="grid gap-3 grid-cols-3">
<div>
<img src="Bwk8bcQH6oLQn1xjzdacPBckn8d" src-width="1000" src-height="500" align="center"/>
</div>
<div>
<img src="DkwibdF3ooVi0KxttdocdoQ5nPh" src-width="400" src-height="354" align="center"/>
</div>
<div>
<img src="M9hDb8WXzo7TU5xg4xtcvArPnxe" src-width="410" src-height="404" align="center"/>
</div>
</div>

Iframe

飞书内的 内嵌网页,将会以 Ifream 的 HTML 标签来输出。

例如:

md
<iframe src="https://www.bilibili.com/video/BV1L94y1t7Yb/"/>

License

MIT