关于 pdf-creator
pdf-creator 是将 Markdown 转换为 PDF 的文档技能,支持中文字体、主题和批量转换。它会根据内容与主题选择渲染后端,并提供针对表格边框的视觉检查流程。
主要功能
- 01Markdown 转 PDF
- 02支持中文字体与多种主题
- 03按内容和主题选择渲染后端
- 04批量转换 Markdown 文件
- 05检查 PDF 表格边框渲染
适用场景
- 01制作中文 PDF 文档
- 02生成适合打印或手机阅读的版本
- 03批量转换 Markdown 文档
- 04检查 PDF 表格边框是否被裁切
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ daymade/ claude-code-skills --skill pdf-creator安装后在 Claude Code 中输入/pdf-creator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/illustrated-manual.mdscripts/batch_convert.pycheck_table_borders.pymd_to_pdf.pyscripts/tests/test_backend_routing.pytest_cjk_code_blocks.pytest_cjk_tables.pytest_executable_copy.pytest_list_rendering.pytest_relative_images.pytest_self_check_preview.pytest_table_border_check.pytest_typography_lint.pythemes/cjk-auto.cssdefault.cssmobile.csswarm-terra-menu.csswarm-terra.css详细介绍
PDF 创建器
使用 Markdown 创建专业 PDF 文档,支持中文字体和主题系统。
对于现有的 .docx 源文件,请改用 docx-creator/references/word-to-pdf.md。
请根据权威输入格式和输出后缀进行选择。
将制造商的 PDF 手册改编为简明的中文图文指南时,请先阅读图文手册工作流,再开始撰写。整理好 Markdown 源文件后,继续遵循此 Skill 常规的主题、后端和视觉自检要求。
快速开始
以下所有 scripts/… 路径均相对于此 Skill 自身的目录——请从该目录运行命令,或替换为绝对路径。从存放 Markdown 文件的目录运行会导致 Failed to spawn: 'scripts/md_to_pdf.py'。可以省略输出路径,系统会根据输入文件的基本名称生成输出路径(input.md → input.pdf,位于输入文件所在目录)。
相对图片路径请保持相对于输入 Markdown 文件所在的目录。 两个后端的转换器都会使用该目录,即使临时 HTML 文件和命令的工作目录位于其他位置。
# Default theme
uv run --with weasyprint scripts/md_to_pdf.py input.md output.pdf
# Source directory and filename containing spaces and Chinese
uv run --with weasyprint scripts/md_to_pdf.py \
"guide source/操作指南.md" "guide source/操作指南.pdf"
# Use a named theme
uv run --with weasyprint scripts/md_to_pdf.py input.md --theme warm-terra
# Mobile theme
uv run --with weasyprint scripts/md_to_pdf.py input.md --theme mobile
# Batch convert all markdown files with a specific theme
uv run --with weasyprint scripts/batch_convert.py *.md --theme warm-terra --no-preview
# No weasyprint? Use Chrome backend (auto-detected if weasyprint unavailable)
python scripts/md_to_pdf.py input.md --theme warm-terra --backend chrome
# List available themes
python scripts/md_to_pdf.py --list-themes dummy.md
主题
使用“快速开始”中的 --list-themes 查看可用主题名称和说明。阅读 themes/*.css,了解页面布局、字体族、颜色和各主题的布局规则。
创建新主题:复制 themes/default.css,修改后保存为 themes/your-theme.css。
打印版与手机版:选择合适的主题
| 场景 | 推荐主题 | 原因 |
|---|---|---|
| A4 纸打印、讲义、合同 | default | 打印版布局 |
| 培训材料、课程大纲 | warm-terra | 培训布局 |
| 通过微信发送、手机阅读 | mobile | 手机布局 |
| 同时需要打印版和手机版 | 使用不同主题运行两次 | 此 Skill 运行速度快,可生成两个版本 |
**选择规则:**如果用户未指定,培训或课程内容默认使用 warm-terra,正式文档默认使用 default——但当文档表格的列内容长度不均(如日程安排、明细列表)时,优先选择 cjk-auto,而不是 default。仅当输出渠道不明确时,才询问“是否需要手机版?”
后端
脚本会根据内容 × 主题自动检测最合适的后端——主题这一半很重要,因为 CJK 内容之所以需要 Chrome,原因在于主题的字体栈特性,而不是文本使用了中文:
- CJK + 宋体/黑体主题(
default、cjk-auto)→ weasyprint。这些主题会嵌入 CID TrueType 字体,所有阅读器都能渲染,因此 Chrome 毫无优势,还会导致下文所述的裁切。 - CJK + 苹方主题(
warm-terra、mobile、warm-terra-menu,以及不在安全列表中的任何主题)→ Chrome。weasyprint 会将 PingFang SC 子集嵌入为 CID Type 0C OpenType 字体,macOS Preview/Adobe Reader 无法渲染——即使 Chrome 自带的 PDF 查看器显示正常,收件人的设备上仍会出现乱码。 - 非 CJK 内容 → weasyprint(速度更快,无需启动浏览器)。
路由逻辑由 scripts/tests/test_backend_routing.py 固定。你自行添加的主题会被视为苹方类主题,除非你将其添加到 md_to_pdf.py 中的 _WEASYPRINT_SAFE_CJK_THEMES——只有确认其 CJK 字体为 CID TrueType 后,才能这样做。
| 后端 | 安装 | 优点 | 缺点 |
|---|---|---|---|
weasyprint | pip install weasyprint | CSS 渲染精准,无需浏览器,不会裁切溢出内容 | 将 PingFang SC 子集嵌入为 CID Type 0C——在 Preview/Adobe 中无法阅读 |
chrome | 已安装 Google Chrome | 无 Python 依赖,能正确渲染 PingFang | 会裁切超出 @page 框的所有内容(见下文) |
可用 --backend chrome 或 --backend weasyprint 覆盖;显式指定的标志始终优先于自动检测。
主题不会告诉你实际使用了哪个后端。 当 weasyprint 无法导入时,default/cjk-auto 渲染会回退到 Chrome——stderr 会显示警告,但退出码为 0。查看 Generated: 行中的 backend= 字段,确认实际使用的后端;决定是否适用下文 Chrome 专属步骤的是这个字段,而非主题名称。
Chrome 会裁切,而不只是溢出
Chrome 会在 @page 内容框处为每页添加一个 re W* n 裁切路径。超出该框的内容仍存在于 PDF 的对象层中,但永远不会被绘制出来。以 A4 页面和 margin: 2.5cm 2cm 2cm 2cm 为例:裁切路径止于 538.90pt,而表格右侧边框位于 545.18pt——因此边框会被悄然截掉。
这不是“宽表格”问题——在 default 和 cjk-auto 主题下,每张表格都会如此。 两种主题都设置了 table { width: 100% };default 使用固定列宽,而 cjk-auto 会用内容感知的自动布局覆盖排版补丁。即使是两列表格,也会铺满整个内容宽度。实测发现,一个简单的 | 周一 | 周二 | 表格与六列收费表的裁切情况完全相同。内容宽度无关紧要;真正越界的是主题自身的 width: 100% 加上单元格内边距。
溢出本身是有意为之:CJK 排版层设置 overflow-wrap: normal,正是为了让内容溢出,而不是在词元中间断行(见下文“CJK 排版”)。这种权衡在 weasyprint 下是安全的,在 Chrome 下却会造成破坏。
这个问题在多次交付中一直未被发现,并非预览有误——而是症状看起来像有意设计。 最后一列的文本完整无缺,间距也正确;只有一条极细的边框消失了,看起来像是样式选择。与此同时,下方的视觉检查清单会引导你留意文本被截断的情况,而这里恰恰没有发生这种情况。
光栅化器会遵循裁切路径,因此本脚本已生成的预览 PNG(pdftoppm,130 dpi)确实能显示此缺陷,400 dpi 的渲染结果也一样——在 400 dpi 下,预期边框两侧共 25 个像素列中完全没有墨迹。而不会显示该问题的是任何读取坐标而非像素的检查——pdfplumber 仍会报告在 545.18pt 处存在一个矩形,因为该对象确实存在。
与其依赖人眼发现缺失的细线,不如运行检查。检查有两种形式;对于 Chrome 渲染的 PDF,只有第二种才是判定依据。
# Form 1 — one file. Compares ink against the PDF's own object layer.
uv run --with pdfplumber --with pillow --with numpy scripts/check_table_borders.py out.pdf
形式 1 会获取每个检测到的表格的列边界,统计其中有多少条边界在 pdftoppm 栅格图像中确实有墨迹;如果 PDF 中存在某条边界,但纸面上没有,就会报出该边界并以非零状态退出。它会报告测量了多少个表格;如果一个都没找到,就会显示 NOTHING CHECKED,而不是 PASS——未能检测到表格的文档并未通过检查,只是被跳过了。
边界取自单元格网格,而非原始垂直边缘,因为 <hr> 的端帽和内嵌 <code> 跨度的背景,在基于边缘的读取器看来都与列线完全相同。在真实知识库生成的 49 份 WeasyPrint PDF 上进行测量,其中 46 份的几何结构曾被基于边缘的版本检查;该版本在这 46 份中有 34 份检查失败。仍有一个限制:对于其他工具生成的 PDF,pdfplumber 有时会把装饰元素拼成一个从未存在过的表格,并为其报告线条。如果本技能未生成的 PDF 检查失败,应将其视为需要查看的提示,而非定论。
它无法单独判定 Chrome 渲染是否通过,因为裁剪会以两种不同方式破坏证据。 Chrome 会保留与裁剪区域相交的几何结构——形式 1 能捕获这种情况,因为该线条本应存在,却没有绘制出来;但它会丢弃完全位于裁剪区域之外的几何结构,而且从未写入对象层的线条也不会被检查。实测发现:一个设置了垂直线条、但没有单元格填充的表格,打印结果为 5/5 promised rules painted — PASS,但它的右边框实际上已经消失。附带主题只是碰巧避开了这个问题;它们的单元格背景填充会与裁剪区域相交,并在边框所在位置留下边缘,供形式 1 查找。
因此,如果主题使用 Chrome,且文档中有表格,请用另一个后端渲染同一份源文件并进行比较:
# Form 2 — render a reference with the other backend, then compare.
# Use the SAME --theme as the deliverable; only the backend differs.
uv run --with weasyprint scripts/md_to_pdf.py doc.md /tmp/ref.pdf \
--theme warm-terra --backend weasyprint --no-preview
uv run --with pdfplumber --with pillow --with numpy \
scripts/check_table_borders.py out.pdf --reference /tmp/ref.pdf
退出代码:0 检查通过,1 至少有一项检查未通过,2 无法运行检查,3 未检测到表格,因此未进行测量。3 不代表通过:如果文档确实有表格,那么其样式没有绘制出 pdfplumber 能找到的线条,因此这项检查无法判定该表格——请改为自行查看表格右边缘的栅格图像,并在交接说明中注明检查门禁未运行。对于子集 CJK 字体,pdfplumber 运行时会打印 Could not get FontBBox from font descriptor;这是解析器噪声,不是检查结果。
参考文件只是测量标尺,绝不是交付物——它很可能也存在 CID Type 0C 问题,而这正是该主题最初切换到 Chrome 的原因;不过这不会影响其几何结构。
两个文件都会进行墨迹检查,而且规则数量会双向比较,因此传入文件的顺序不会决定是否检查损坏的文件。这一点比听起来更重要:对于 Chrome 裁剪而非丢弃的边框,两个渲染结果的规则数量相同——几何结构仍然存在,只是没有绘制出来——因此数量比较不会发现问题,只有对右侧文件进行墨迹检查才能找出问题。在参考文件也进行墨迹检查之前,如果将被裁剪的文件作为 --reference 传入,检查会直接给出 PASS。
双向数量比较的规则如下:规则数量少于参考文件,表示渲染器丢弃了部分线条;数量更多,则表示参数顺序颠倒,或两个文件并非同一份文档。比较的是数量而非位置,也是在整个文档范围内比较而非逐页比较,因为两个后端会以不同方式拆分同一份源文件——在一张 60 行的 CJK 表格上测得,两种拆分页数由行内容决定:default 为 5 页对 3 页,warm-terra-menu 为 3 页对 15 页,而规则数量始终相同。
在 5 种主题 × 单页和多页 × 两种参数顺序的组合上完成校准:不含被裁剪文件的 12 组都在两种顺序下通过;包含被裁剪文件的 8 组也都在两种顺序下被检出。另对 14 份真实 Markdown 文档 × 2 种主题进行了独立测试,没有出现误报。
批量转换
# Default theme, same directory
uv run --with weasyprint scripts/batch_convert.py *.md
# Specific theme, output directory, skip previews for speed
uv run --with weasyprint scripts/batch_convert.py *.md --theme warm-terra --output-dir ./pdfs --no-preview
# Mobile theme for phone reading
uv run --with weasyprint scripts/batch_convert.py *.md --theme mobile --output-dir ./mobile-pdfs --no-preview
# The border check takes several files at once, so a batch is still gated
uv run --with pdfplumber --with pillow --with numpy \
scripts/check_table_borders.py ./pdfs/*.pdf
--no-preview 会关闭视觉自检,这正是批量处理的目的所在,但不会免除检查义务。请像上面一样检查输出文件的边框。这需要检查许多文件;而 --reference 不需要,因此,对于包含表格的 Chrome 渲染文档,批量处理时需要为每份文档单独运行一组配对命令。
反模式:切勿手动调用 pandoc + Chrome
此技能存在的原因: 手动执行 pandoc input.md -o out.html + chrome --headless --print-to-pdf 的工作流会悄然失败,而且很难发现:
| 手动步骤 | 出错情况 | 此技能的修复方式 |
|---|---|---|
pandoc -o out.html | 没有适配 CJK 的 CSS → 中文显示为方框或空白 | 注入 CJK 字体栈和排版补丁 |
Chrome --print-to-pdf | 出现默认页眉/页脚(文件名、日期、URL、页码) | 传入 --no-pdf-header-footer |
macOS 上的 Chrome --print-to-pdf | Chrome 可能写入 PDF 后却不退出(Chrome 154 在传入 --user-data-dir 时总会如此),导致命令挂起;被终止的 Chrome 还会在临时目录中留下 Chrome 应用的副本 | 在 PDF 以 %%EOF 结尾后停止 Chrome,超时后放弃,并传入 --disable-features=MacAppCodeSignClone |
| 没有渲染后检查 | 将“退出代码 0”视为成功;渲染错误被隐藏 | 自动生成逐页 PNG 预览和排版检查 |
| 没有主题系统 | 一刀切;无法在手机上阅读 | 主题选择 |
缺少 batch_convert.py | 编写临时循环,标志参数不一致 | 内置批量模式,支持 --theme |
规则: 对于 Markdown → PDF,请使用此技能,而不是手动执行 pandoc/Chrome 命令。 对于现有的 Word/WPS → PDF,请使用上文所述的 docx-creator 方案。
故障排查
中文字符显示为方框:确保已安装中文字体(Songti SC、PingFang SC 等)。
weasyprint 导入错误:使用 uv run --with weasyprint 运行,或改用 --backend chrome。
代码块中的 CJK 文本乱码(weasyprint):脚本会自动检测含有中日韩字符的代码块,并将其转换为使用支持 CJK 的字体的样式化 div。如果仍有问题,请使用具有原生 CJK 支持的 --backend chrome;但如果文档中含有表格,请使用 scripts/check_table_borders.py <the chrome pdf> --reference <a weasyprint render of the same source> 检查结果——先写目标,再写标志——因为 Chrome 会裁掉超出 @page 框的表格边框,而单文件形式无法检测 Chrome 丢弃而非裁掉的边框(参见上文“Chrome clips, it does not merely overflow”)。或者,在生成 PDF 前将代码块转换为 Markdown 表格。
Chrome 页眉/页脚出现:脚本会传入 --no-pdf-header-footer。如果页眉/页脚仍然出现,你的 Chrome 版本可能不支持此标志,请更新 Chrome。**注意:**如果你绕过此技能并手动使用 Chrome 无头模式,这就是最先出现的症状——请参见上文“反模式”部分。
混合 CJK 和 ASCII 的行内代码在 macOS Preview 中显示为空白(例如 `Terminal/终端` 只渲染出 Terminal/,CJK 部分缺失):weasyprint 会将 PingFang SC 子集嵌入为 OpenType (CID Type 0C),严格的 PDF 阅读器(macOS Preview / Adobe Reader)无法渲染这种格式。Chrome 的 PDF 查看器会自动回退,因此不会暴露此问题。默认主题中已修复:代码字体的 font-family 链会优先使用 CID TrueType CJK 字体(Songti SC / Heiti SC),再使用 OpenType 字体(PingFang SC)。验证方法:使用 pdfplumber 检查 CJK 字符的 font['fontname']——如果其中任何一个引用了 PingFang-SC(CID Type 0C OT),阅读器很可能无法正常渲染。调整字体链顺序,让 CID TrueType 字体优先。
表格第 1 列的短标签在中间断开(例如 4/28(周|二)下|午):pandoc 会根据 Markdown 分隔行中的短横线数量自动生成 <colgroup><col style="width:X%">。对于 | ----- | --- | --- | -------- |(短横线数量不均),pandoc 分配给第 1 列的宽度约为 17%——不足以容纳 9 个字符的 CJK 标签。特异性相同时,行内 style="" 优先于外部 CSS,因此 td:first-child { width:... } 会被静默覆盖。默认主题中已修复:table colgroup col { width: auto !important } 会抵消 pandoc 的宽度提示,让 table-layout: fixed 平均分配列宽(4 列表格中每列占 25%)。验证方法:运行 pandoc input.md -t html | grep colgroup——如果输出中出现 <col style="width:X%">,则会受到此问题影响。**适用范围:**此抵消规则仅存在于 default.css 中;warm-terra 和 mobile 主题采用不同策略(对 th/td 设置 nowrap,并允许最后一列换行;以及完全自然流式换行),因此有意省略了该规则。此抵消规则由 scripts/tests/test_cjk_tables.py::test_default_theme_neutralizes_pandoc_colgroup_hint 测试锁定。
视觉自检(必须执行——不得跳过)
**这不是可选项。**每次生成 PDF 后,脚本都会自动:
- 通过
pdftoppm(poppler-utils)将每一页转换为 PNG,并存入系统临时目录下的<pdf-name>/子目录(不会放在 PDF 旁边——预览图是临时的自检产物,不得留在工作树 / git 仓库中)。运行时会打印目录路径Previews:,以及已有的First page:路径。Poppler 可能会根据页数为页码补零;请枚举实际的page-*.png文件,而不要自行拼接文件名。 - 打印结构化的自检清单,提醒调用者目视检查每一页
- 运行排版检查,检测 CJK 行断行反模式 为什么必须执行:“PDF 生成成功”≠“渲染结果符合 Markdown 意图”。常见的隐性故障包括:
- 多个段落合并为一个(CommonMark 会将连续的非空行视为软换行)
- 表格超出页边距
- 表格右边框缺失,但文本完整(Chrome 裁剪——这是列表中唯一一种看起来不像故障的情况;由
scripts/check_table_borders.py判定;对于 Chrome 渲染结果,只有其--reference形式能给出结论) - 缺少中日韩文字/emoji 字形
- 代码块乱码
- Chrome 默认页眉/页脚(如果绕过此技能)
工作流,在生成与交付之间的暂停点执行:
-
阅读页面。 列出并逐一
Read打印出的Previews:目录中的每张实际 PNG,并与 Markdown 源文件核对。如果渲染结果与意图不符,修正 Markdown(使用真正的-列表代替伪列表、插入空行、重组表格),然后重新运行。脚本不会静默“修复”非标准 Markdown——那会掩盖源文件有误这一信号,导致同一 Markdown 在其他处理器(Obsidian、GitHub、VS Code 预览)中再次渲染错误。 -
如果文档包含任何表格,请对 PDF 运行
scripts/check_table_borders.py——如果渲染经过 Chrome,则运行其--reference形式;这是在此情况下唯一能给出结论的形式(两种形式都在上文“Chrome 会裁剪,而不只是溢出”一节中介绍)。第 1 步无法替代此检查。边框缺失看起来像一种样式选择,而第 1 步的检查清单会让你留意文本是否被截断,恰恰这次并没有发生这种情况。不要仅凭第 1 步就交付包含表格的 PDF。 -
如果 PDF 包含命令,请检查可执行命令的复制情况。 作为作者,从最终 PDF 中提取命令块(例如使用
pdftotext -layout),排除说明文字和页脚,同时保留换行。将其与 Markdown 源文件进行比较,检查令牌、引号、管道符、重定向符和续行语义。代码显示正确并不能证明复制准确:换行可能导致一行变成独立命令,或让|出现在新的 Shell 语句开头。对于 Shell,sh -n只能检查语法,无法证明参数或重定向目标未被更改。如果需要通过执行来检查含义,请使用无害的参数捕获桩。如果换行改变了命令,请在源文件中的安全位置手动添加显式续行符,重新构建,并再次提取最终 PDF。不要自动插入反斜杠、将所有代码块改为nowrap,也不要仅为测试复制情况而执行实际诊断命令。此比较由作者执行;脚本的检查清单不会强制执行此项。
这些检查无法发现所有问题。PNG 由 pdftoppm 生成,它会渲染 CID Type 0C 字体,而 macOS Preview 和 Adobe Reader 会将其显示为空白——因此,字体嵌入缺陷在第 1 步中可能看起来完全正常,但在接收者的设备上却无法阅读。这个问题要通过主题路由处理,而不是靠目视检查(参见“后端”);需要手动运行的检查位于“故障排除”下的“包含混合中日韩文字 + ASCII 的行内代码”一节。
批处理/非交互式运行时,可使用 --no-preview 禁用预览:
python scripts/md_to_pdf.py input.md output.pdf --no-preview
需要 pdftoppm(macOS 上运行 brew install poppler)。如果未安装,脚本会记录一条提示并跳过预览生成,但仍会生成 PDF。
中日韩文字排版(默认行为)
脚本会自动应用适用于中日韩文字的处理方式——不会修改用户的 Markdown 源文件或主题 CSS 文件:
第 1 层:CSS 补丁(自动注入)
_load_theme() 会将 CJK 排版 CSS 补丁追加到已加载的主题 CSS 中。该补丁:
table { table-layout: fixed; width: 100% }— 列宽相等,可避免 weasyprint 自动布局在相邻列内容多出 5 倍时,将某一列挤压到约 10% 的宽度。cjk-auto主题会通过table-layout: auto !important和单元格上的white-space: normal !important覆盖此设置,分配适应内容的列宽,同时允许较长的单元格内容换行。td, th { word-break: keep-all; overflow-wrap: normal; line-break: strict }— 不要拆开 CJK 字符。overflow-wrap: normal(而非break-word)体现了有意的权衡:允许内容略微溢出,而不是退回到词语中间断行。相关理由记录在md_to_pdf.py的CJK typography patch (auto-injected注释块中,并由scripts/tests/test_cjk_tables.py保证。th { white-space: nowrap }— 短表头保持在一行中,以便列宽可预测。
这会在不触碰用户源文件的情况下,静默修复最常见的反模式(单元格内容被强制在 CJK 字符之间换行,导致每行只有一个字符)。磁盘上的用户主题 CSS 文件永远不会被修改。
第 2 层:排版检查(渲染后检测,捕获其余问题)
生成 PDF 后,脚本会对每一页运行 pdftotext -layout,并扫描“中文文案排版指北”中提到的已知 CJK 反模式:
- 单个 CJK 字符独占一行(即使经过第 1 层处理,单元格仍然太窄)
- 行尾为
(,且内容出现在下一行(括号对被拆开) - 行首为
)(与前一行的括号配对被拆开) - 短行以表示语意未完的标点
、,;:结尾
发现的问题会连同页码和行号一起输出到 stderr。它们是警告,不是错误——PDF 仍会生成。作者看到发现的问题后可自行决定:
- 接受(例如,长文档中出现一个孤立字符或许可以接受)
- 缩短有问题的单元格内容,使其适应列宽
- 调整结构(例如,将较长的内容移到表格下方的段落中)
为什么不静默地自动修复所有问题?
第 2 层会刻意避免修改 Markdown。静默重写非标准 Markdown(例如,将伪列表扩展为真正的列表)会掩盖源内容有误这一信号,导致相同的 Markdown 在其他处理器中仍然渲染不正确。第 1 层可以接受,因为它修补的是渲染行为,针对的是已经符合标准的 Markdown(标准表格只是恰好被 weasyprint 渲染得不符合 CJK 排版要求),而不是 Markdown 源文件本身。
已知限制
当单个单元格的内容只比可用列宽略长时(例如,等分列宽后,一个 9 个字符宽的单元格中有 10 个 CJK 字符),即使设置了 keep-all,weasyprint 仍会退回到强制换行。第 1 层无法修复此问题——第 2 层会将其捕获,并提示作者缩短单元格内容或调整结构。