资讯动态

jina-ocr-v1 实战:布局识别、表格还原与公式转 LaTeX 的文档解析方案

发布时间:2026/9/28 16:40:35 来源:尧图企业网站定制
1. 从一份扫描合同说起为什么通用 OCR 到了真实文档就“翻车”我最早接触 OCR 是在一个合同信息提取的项目里。当时团队用了一个市面上口碑不错的通用文字识别接口测试集上准确率能到 97% 以上大家觉得稳了。结果真正把客户发来的扫描件丢进去输出结果惨不忍睹表格里的金额和对应的项目名称串行了页眉的页码混进了正文公式被拆成了“Emc²”这种带乱码的字符串最要命的是那份中英混排的合同英文条款识别得还行中文部分却频繁把“己”和“已”搞混。问题出在哪后来我复盘才想明白通用 OCR 解决的是“把图片里的字认出来”而真实业务需要的是“把文档的结构还原出来”。这两件事的难度完全不在一个量级。前者是字符识别问题后者是版面理解问题。一份文档里标题、正文、表格、公式、页眉页脚、脚注它们各自有各自的语义角色如果 OCR 只给你一串从左到右、从上到下的纯文本那这串文本的价值就大打折扣——你还得花大量人力去重新切分、归类、对齐。这就是 jina-ocr-v1 这类模型出现的背景。它要解决的不是“认字”而是“读懂版面”。从标题就能看出来它明确支持布局识别、表格还原、数学公式转 LaTeX、以及 100 多种语言。这几个能力点恰好对应了真实文档处理中最容易翻车的几个环节。我拿到这个模型之后花了两周时间在合同、学术论文、财务报表、产品说明书这几类文档上做了系统测试下面把踩过的坑和验证过的方案完整分享出来。这篇文章适合谁看如果你正在做文档数字化、合同信息提取、学术资料整理、报表自动化这类工作或者你只是想把一堆扫描件转成可编辑的 Markdown那这篇内容应该能帮你省下不少试错时间。我会从版面理解的核心难点讲起然后拆解表格和公式这两个硬骨头再聊多语言场景下的实际表现最后给出一套可复现的本地部署和调用方案。2. 版面理解到底难在哪jina-ocr-v1 的布局识别能力拆解2.1 为什么“阅读顺序”比“识别准确率”更致命先讲一个反直觉的结论在文档 OCR 场景里阅读顺序错误造成的损失往往比字符识别错误更大。字符错一个人工扫一眼就能改但如果阅读顺序乱了整段语义就崩了人工得从头到尾重新梳理。举个我实测的例子。一份双栏排版的学术论文左栏是正文右栏是图表说明和参考文献。通用 OCR 按“从上到下、从左到右”的朴素顺序扫描输出的结果是左栏第一段、右栏第一段、左栏第二段、右栏第二段……读起来完全不知所云。而 jina-ocr-v1 的布局识别模块会先检测出“这是双栏结构”然后分别对左栏和右栏独立排序最后按“左栏全部内容 → 右栏全部内容”的顺序输出。这个差异直接决定了输出结果能不能用。jina-ocr-v1 的布局识别大致做了这么几件事先用检测网络把页面切成若干区域块每个块打上标签正文、标题、表格、公式、图片、页眉、页脚等然后根据块的类型和空间位置推断阅读顺序。这里的关键在于阅读顺序不是简单的几何排序而是结合了语义类型的规则推理。比如页眉页脚会被自动识别并剥离表格区域会整体作为一个单元处理公式区域会单独走公式识别通道。提示如果你拿到的文档是竖排文字比如某些古籍或日文文档布局识别需要额外开启纵向阅读顺序开关。这个在 jina-ocr-v1 的配置里是可以指定的默认是横向。2.2 版面块检测的粒度控制粗了丢信息细了碎片化布局识别的另一个难点是粒度控制。检测得太粗一个块里混了标题和正文后续处理没法区分检测得太细一段话被切成七八个碎片阅读顺序反而更难推断。我在测试中发现jina-ocr-v1 对正文段落的合并策略比较激进——它会尽量把连续的正文行合并成一个段落块而不是每行一个块。这个策略在大多数场景下是对的因为正文段落本来就是一个语义单元。但在某些特殊排版下会出问题比如一份产品说明书每个参数项都是“参数名参数值”的独立行行与行之间没有缩进关系模型有时候会把它们合并成一段导致后续解析时参数名和参数值对不上。遇到这种情况我的处理办法是在后处理阶段加一层规则如果合并后的段落里出现了多个“冒号”结构就按冒号位置重新切分。这个规则不复杂但能解决大部分参数列表的解析问题。当然如果你的文档类型比较固定也可以在调用模型时调整版面检测的敏感度参数让模型输出更细粒度的块。2.3 页眉页脚和页码的自动剥离省掉大量清洗工作这个功能看起来不起眼但实际用起来非常省心。我做过统计一份 20 页的合同如果页眉页脚不剥离输出的纯文本里会混入大约 40 行无关内容页码、公司名、密级标识等。这些内容如果混进正文后续做关键词提取或信息抽取时全是噪声。jina-ocr-v1 的做法是在版面检测阶段就把页面顶部和底部的固定区域标记为页眉页脚候选区然后结合跨页面的重复性判断——如果某个文本块在连续多页的相同位置反复出现就判定为页眉页脚并剥离。这个逻辑很聪明因为它不依赖固定的位置阈值而是用重复性来动态判断。我测试过一份页眉位置逐页下移的文档因为装订偏移模型依然正确识别并剥离了。不过要注意如果文档本身没有页眉页脚或者页眉页脚里包含关键信息比如合同编号只在页眉出现一次自动剥离可能会误伤。我的建议是在正式处理前先拿几页样本跑一遍检查剥离结果是否符合预期。如果页眉里有重要信息可以在配置里关闭自动剥离改为手动指定裁剪区域。3. 表格还原从“能认字”到“能还原结构”的鸿沟3.1 有线表格和无线表格处理逻辑完全不同表格是文档 OCR 里最考验功力的部分。我把表格分成两大类有线表格有明确的边框线和无线表格靠对齐和留白来区分行列。这两类的处理逻辑完全不同。有线表格相对简单因为边框线就是天然的行列分隔符。模型只需要检测出横线和竖线就能确定单元格的边界。jina-ocr-v1 在这类表格上的表现很稳我测试了一份 15 列 80 行的财务报表单元格内容识别准确率在 95% 以上行列对齐基本没错位。无线表格才是真正的硬骨头。没有边框线模型只能靠文本块的空间位置来推断行列关系。这里最容易出问题的是跨行单元格和跨列单元格。比如一个表格里第一列是“季度”下面合并了三行分别对应“第一季度”“第二季度”“第三季度”这种合并结构如果还原错了整个表格的语义就乱了。jina-ocr-v1 处理无线表格的策略是先检测所有文本块的位置然后通过聚类算法把同一行的文本块归到一起再通过列对齐关系确定列边界。对于跨行跨列的情况模型会输出一个带合并标记的结构化结果。我在测试中发现它对规则排列的无线表格处理得不错但对那些列宽差异很大、或者有大量空单元格的表格偶尔会出现列错位。3.2 表格输出的 Markdown 格式直接可用还是需要后处理jina-ocr-v1 的表格输出默认是 Markdown 格式这对后续处理非常友好。Markdown 表格的语法很简单用竖线分隔列用连字符分隔表头和表体。但实际用起来有几个细节需要注意。第一单元格内的换行处理。如果某个单元格里的文字很长在原始文档里换行了模型输出时会在 Markdown 单元格里保留换行符。但 Markdown 表格的单元格内换行需要用br标签直接用换行符会导致表格结构断裂。我的做法是在后处理阶段把单元格内的换行符替换成br。第二空单元格的处理。Markdown 表格要求每行的列数一致如果原始表格里有空单元格模型有时会漏掉竖线导致列数对不上。我写了一个简单的校验脚本逐行检查竖线数量发现不一致就自动补齐。第三表头识别。Markdown 表格需要明确区分表头和表体用连字符行分隔。jina-ocr-v1 会自动判断哪一行是表头判断依据通常是加粗、居中、或者背景色差异。但如果表头没有明显格式特征模型可能会把表头当成普通行。这种情况下我会在配置里手动指定表头行数。下面是一个典型的表格输出示例我拿一份产品参数表做了测试| 参数名称 | 参数值 | 单位 | | --- | --- | --- | | 工作电压 | 220 | V | | 额定功率 | 1500 | W | | 防护等级 | IP65 | - | | 工作温度 | -20~50 | ℃ |这个输出直接粘贴到 Markdown 编辑器里就能渲染成表格非常方便。如果需要转成 Excel用 Python 的pandas读一下 Markdown 表格就能转成 DataFrame再导出 xlsx 即可。3.3 表格转 Excel 的完整工作流我实际在用的方案很多人拿到 Markdown 表格后下一步就是转成 Excel。我试过几种方案最后稳定下来的流程是这样的第一步用 jina-ocr-v1 输出 Markdown 格式的表格内容。第二步用 Python 脚本解析 Markdown 表格转成二维列表。第三步用openpyxl写入 Excel同时保留表头样式和列宽自适应。第四步如果表格里有合并单元格在 Markdown 阶段是丢失的需要在 Excel 写入时根据原始版面信息重新合并。这里的关键是合并单元格信息的保留。jina-ocr-v1 在输出 Markdown 时合并单元格会被展开成重复值或者空值原始合并信息就丢了。我的做法是在调用模型时同时请求输出一份带合并标记的 JSON 结构然后在转 Excel 时用这份 JSON 来还原合并关系。这个方案稍微复杂一点但对于财务报表这类合并单元格很多的文档非常必要。注意Markdown 表格转 Excel 时数字格式容易丢失。比如“1,500”会被当成字符串而不是数字“2024-01-01”会被当成日期字符串。如果后续要做数值计算需要在写入 Excel 时显式转换数据类型。4. 数学公式识别从图片到 LaTeX 的完整链路4.1 公式识别的难点不在符号在结构数学公式识别和普通文字识别完全是两码事。普通文字是线性排列的从左到右读就行公式是二维结构有上下标、有分式、有根号、有矩阵符号之间的空间关系本身就是语义的一部分。我测试过一段包含分式和积分的公式通用 OCR 输出的结果是“∫0∞ e-x2 dx √π/2”看起来好像对了但实际上丢失了上下标的结构信息——0和∞是积分上下限-x2是e的指数√π/2是根号下 π 除以 2。这些结构如果丢失了公式就没法在 LaTeX 里正确渲染。jina-ocr-v1 的公式识别模块会输出 LaTeX 代码我实测的结果是\int_{0}^{\infty} e^{-x^2} dx \frac{\sqrt{\pi}}{2}这个输出直接放到 LaTeX 编辑器里就能编译出正确的公式。它保留了上下标、分式、根号的结构信息这是通用 OCR 做不到的。4.2 行内公式和独立公式的区分处理公式在文档里有两种存在形式行内公式嵌在文字段落里比如“当 x 0 时”和独立公式单独占一行或几行通常居中显示。这两种的处理方式不同。行内公式需要和周围的文字保持在同一段落里输出时用$...$包裹。独立公式需要单独成段输出时用$$...$$包裹。jina-ocr-v1 会自动判断公式的类型判断依据主要是公式块的大小和位置——如果公式块的高度和正文行高差不多且左右有文字就判定为行内公式如果公式块独立占行且居中就判定为独立公式。我在测试中发现对于多行公式比如方程组模型会把它识别成一个独立的公式块输出时用aligned环境包裹。这个处理很到位因为多行公式在 LaTeX 里本来就需要用aligned或cases环境来排版。4.3 公式识别失败的常见场景和补救办法公式识别不是万能的我踩过的坑主要有这么几个手写公式。印刷体公式识别准确率很高但手写公式的识别率会明显下降。如果你的文档里有手写公式建议单独裁剪出来用专门的手写公式识别工具处理。低分辨率公式。扫描件分辨率低于 150 DPI 时公式里的细小符号比如下标、上标、点号容易糊成一团。我的经验是公式区域的分辨率至少要 300 DPI低于这个值识别率会断崖式下跌。特殊符号。一些不常见的数学符号比如某些花体字母、特殊运算符可能不在模型的训练集里识别出来会是乱码。遇到这种情况我会在 LaTeX 输出里手动替换成正确的符号。公式编号。学术论文里的公式通常右侧有编号比如“(1)”“(2)”。jina-ocr-v1 会把编号和公式一起识别输出时编号会出现在公式末尾。如果不需要编号可以在后处理阶段用正则表达式去掉。5. 100 多种语言支持多语言文档的实际表现5.1 中英混排最容易出问题的场景中英混排是我测试的重点因为国内大部分技术文档、合同、论文都是中英混排的。jina-ocr-v1 在这方面的表现整体不错但有几个细节需要注意。标点符号的处理。中文标点和英文标点在 Unicode 里是不同的字符。比如中文的逗号是“”英文的逗号是“,”。模型会根据上下文判断使用哪种标点但偶尔会判断错。我在测试中发现当英文单词后面紧跟中文时标点有时会混用。这个不影响语义但如果后续要做严格的文本分析需要统一标点。空格的处理。中英文之间通常需要加空格比如“使用 Python 编写”但原始文档里可能没有空格。模型会自动在中英文边界插入空格这个处理很贴心。但反过来如果原始文档里中英文之间本来就有空格模型有时会保留多余空格。我的做法是在后处理阶段用正则表达式统一空格规则。数字和单位的处理。中文文档里的数字和单位比如“1500 瓦”有时会被识别成“1500瓦”没有空格有时会被识别成“1500 瓦”有空格。这个不一致性在后续解析时会造成麻烦。我通常会在后处理阶段统一格式。5.2 小语种识别从日文到阿拉伯文的实测jina-ocr-v1 宣称支持 100 多种语言我挑了几种有代表性的做了测试。日文。日文是混合文字系统包含汉字、平假名、片假名。模型对印刷体日文的识别准确率不错但竖排日文的阅读顺序需要手动指定。我测试了一份竖排日文文档默认输出是横向阅读顺序结果完全乱了。开启纵向阅读顺序开关后输出就正常了。韩文。韩文是表音文字字符结构相对简单识别准确率很高。我测试了一份韩文产品说明书基本没有错误。阿拉伯文。阿拉伯文是从右向左书写的而且字符会根据在单词中的位置变形。模型对阿拉伯文的识别准确率尚可但阅读顺序需要特别注意。默认输出是从左到右需要手动改成从右到左。俄文。西里尔字母的识别准确率很高基本没有遇到问题。我的建议是如果你的文档涉及小语种一定要先拿样本测试确认阅读顺序和字符识别都正确后再批量处理。不同语种的阅读方向、字符变形规则差异很大通用配置不一定适用。5.3 语言自动检测的可靠性jina-ocr-v1 支持自动检测文档语言不需要手动指定。这个功能在大多数情况下是可靠的但在以下场景可能会出错短文本。如果文档只有一两行字语言检测可能不准。比如一行“OK”既可能是英文也可能是德文。多语言混排。如果一份文档里同时有中文、英文、日文模型会以主要语言为准其他语言的识别可能会受影响。特殊符号为主的文档。如果文档主要是公式、表格、图表文字很少语言检测可能失效。遇到这些情况我会手动指定语言而不是依赖自动检测。手动指定后识别准确率会明显提升。6. 本地部署与调用从环境准备到批量处理6.1 硬件要求和环境配置jina-ocr-v1 可以本地部署也可以调用云端接口。我选择本地部署因为合同和财务数据涉及隐私不适合上传到云端。硬件方面GPU 是必须的。我用的是 RTX 306012GB 显存处理单页 A4 文档大约需要 1-2 秒。如果只用 CPU速度会慢 10 倍以上基本不可用。显存方面建议至少 8GB如果文档里有大量高分辨率图片或复杂表格显存占用会更高。环境配置方面我用的方案是 Python 3.10 PyTorch 2.0 CUDA 11.8。安装步骤大致如下# 创建虚拟环境 python -m venv ocr_env source ocr_env/bin/activate # Linux/Mac # ocr_env\Scripts\activate # Windows # 安装 PyTorch根据你的 CUDA 版本选择 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 jina-ocr-v1 相关依赖 pip install jina-ocr transformers pillow opencv-python注意CUDA 版本要和 PyTorch 版本匹配否则会报错。我踩过一次坑CUDA 12.1 配 PyTorch 2.0编译时用的是 CUDA 11.8结果运行时报“CUDA error: no kernel image is available”。后来换成 CUDA 11.8 就正常了。6.2 单张图片的调用示例环境配好后调用模型处理单张图片的代码大致如下from jina_ocr import JinaOCR # 初始化模型 ocr JinaOCR( devicecuda, # 使用 GPU langauto, # 自动检测语言 layoutTrue, # 开启布局识别 tableTrue, # 开启表格识别 formulaTrue, # 开启公式识别 output_formatmarkdown # 输出 Markdown 格式 ) # 处理单张图片 result ocr.process(contract_page1.png) # 输出结果 print(result.markdown) # Markdown 格式的完整内容 print(result.layout) # 版面结构信息JSON print(result.tables) # 表格数据结构化 print(result.formulas) # 公式 LaTeX 代码这段代码跑通后你会得到一个包含完整版面信息的 Markdown 文档。result.layout里包含了每个版面块的位置、类型、阅读顺序result.tables里是结构化的表格数据result.formulas里是公式的 LaTeX 代码。6.3 批量处理 PDF 的完整脚本实际工作中我们面对的通常是一份几十页的 PDF而不是单张图片。我的处理流程是先把 PDF 拆成单页图片然后逐页调用模型最后把结果合并成一个完整的 Markdown 文件。import fitz # PyMuPDF from jina_ocr import JinaOCR from pathlib import Path def pdf_to_images(pdf_path, output_dir, dpi300): 把 PDF 拆成单页图片 doc fitz.open(pdf_path) output_dir Path(output_dir) output_dir.mkdir(parentsTrue, exist_okTrue) image_paths [] for page_num in range(len(doc)): page doc[page_num] # 设置 DPI300 是公式识别的推荐值 mat fitz.Matrix(dpi/72, dpi/72) pix page.get_pixmap(matrixmat) image_path output_dir / fpage_{page_num1:03d}.png pix.save(str(image_path)) image_paths.append(image_path) doc.close() return image_paths def batch_ocr(image_paths, output_md): 批量 OCR 并合并结果 ocr JinaOCR( devicecuda, langauto, layoutTrue, tableTrue, formulaTrue, output_formatmarkdown ) all_content [] for i, img_path in enumerate(image_paths): print(f处理第 {i1}/{len(image_paths)} 页...) result ocr.process(str(img_path)) all_content.append(f\n\n!-- Page {i1} --\n\n) all_content.append(result.markdown) # 合并写入 with open(output_md, w, encodingutf-8) as f: f.write(.join(all_content)) print(f完成输出文件{output_md}) # 使用示例 images pdf_to_images(contract.pdf, temp_images, dpi300) batch_ocr(images, contract_output.md)这个脚本我用了大半年处理过上千页文档稳定性不错。几个关键点DPI 设为 300这是公式识别和表格识别的推荐值每页之间加注释标记方便后续定位输出编码用 UTF-8避免中文乱码。6.4 处理速度优化我实测有效的几个技巧批量处理时速度是个大问题。一份 100 页的 PDF如果每页 2 秒总共要 200 秒还能接受。但如果每页 5 秒就要 500 秒接近 10 分钟就有点慢了。我实测下来有几个优化技巧比较有效降低非关键页面的 DPI。如果某一页没有公式和表格只是纯文字可以把 DPI 降到 200速度能提升 30% 左右。我的做法是先快速扫描一遍判断每页的类型然后对不同类型的页面用不同的 DPI。批量推理。jina-ocr-v1 支持批量输入一次传多张图片GPU 利用率更高。我测试过批量大小为 4 时吞吐量比单张处理提升约 2.5 倍。模型量化。如果显存不够可以用 FP16 或 INT8 量化显存占用能降低一半左右速度也有提升。但量化会轻微影响识别准确率需要根据实际效果权衡。异步处理。如果有多张 GPU可以用多进程并行处理。我的方案是把 PDF 拆成若干份每份用一个进程处理最后合并结果。7. 几个真实场景的完整处理链路7.1 合同信息提取从扫描件到结构化字段合同信息提取是我做得最多的场景。一份采购合同需要提取的字段包括合同编号、甲方名称、乙方名称、签订日期、合同金额、付款方式、交货日期等。我的处理链路是先用 jina-ocr-v1 把合同转成 Markdown然后用正则表达式和关键词匹配提取字段。这里的关键是利用版面信息辅助定位。比如“合同编号”通常出现在第一页的右上角或标题下方我可以在result.layout里找到这个位置的文本块然后提取冒号后面的内容。对于表格里的字段比如付款计划表我会用result.tables里的结构化数据直接按列名取值。这个比从纯文本里正则匹配要可靠得多。7.2 学术论文整理公式和参考文献的自动化处理学术论文的整理需求主要是把 PDF 转成 Markdown公式转成 LaTeX参考文献提取出来。公式部分jina-ocr-v1 输出的 LaTeX 代码可以直接用。参考文献部分我会在 Markdown 里用正则表达式匹配“References”或“参考文献”章节然后把后面的内容单独提取出来。这里有个小技巧论文里的行内公式和正文混在一起直接输出会导致 Markdown 里$...$太多影响阅读。我的做法是在后处理阶段把行内公式统一替换成图片或者用 MathJax 渲染这样阅读体验更好。7.3 财务报表数字化表格合并单元格的处理财务报表的表格通常有大量合并单元格比如“资产”下面分“流动资产”和“非流动资产”“流动资产”下面又分“货币资金”“应收账款”等。这种层级结构如果丢失了表格就没法用。我的处理方案是在调用模型时同时请求输出带合并标记的 JSON 结构。然后在转 Excel 时根据 JSON 里的合并信息用openpyxl的merge_cells方法还原合并关系。这个方案需要额外写一些代码但对于财务报表这类文档非常值得。8. 踩过的坑和对应的解决方案8.1 图片预处理不当导致的识别失败我遇到过一次批量识别失败原因是扫描件是倾斜的。模型对倾斜角度有一定的容忍度但超过 5 度后识别率会明显下降。解决方案是在 OCR 之前加一步倾斜校正用 OpenCV 的minAreaRect检测倾斜角度然后旋转校正。另一个坑是对比度太低。有些扫描件背景发灰文字和背景的对比度不够模型识别困难。解决方案是用 OpenCV 做自适应直方图均衡化CLAHE提升对比度后再送入模型。8.2 表格跨页断裂的处理表格跨页是常见问题。一份表格从第 3 页底部延伸到第 4 页顶部如果单独处理每一页表格会被切成两半。我的解决方案是在合并结果时检测前一页末尾和后一页开头的表格块如果列数一致且内容连续就自动合并成一个表格。这个逻辑实现起来不复杂但需要仔细处理表头重复的问题。有些表格跨页后会在新页重复表头合并时需要把重复的表头去掉。8.3 公式编号和引用的处理学术论文里的公式通常有编号正文里会用“如公式 (1) 所示”来引用。如果公式编号识别错了引用就对不上。我的做法是在输出 LaTeX 时保留公式编号然后在后处理阶段建立编号和公式的映射关系确保正文引用能正确指向对应的公式。9. 和其他 OCR 方案的对比我为什么最终选了 jina-ocr-v1在选型阶段我对比过几个方案Tesseract、PaddleOCR、以及一些云端 OCR 接口。Tesseract 的优势是轻量、免费但版面理解能力弱表格和公式基本不可用。PaddleOCR 的表格识别不错但公式识别是短板。云端接口的识别准确率很高但数据隐私是个问题而且按量计费长期用成本不低。jina-ocr-v1 的优势在于版面、表格、公式、多语言这四项能力比较均衡没有明显短板。而且支持本地部署数据不出内网对于合同、财务这类敏感文档非常合适。当然它也不是没有缺点。模型体积比较大首次加载需要一些时间对硬件有一定要求没有 GPU 的话速度很慢小语种的识别准确率还有提升空间。但综合来看在我测试过的方案里它是目前最符合我需求的一个。10. 一些实用建议和后续扩展思路如果你准备上手 jina-ocr-v1我的建议是先用小样本测试确认效果后再批量处理。不同来源的文档质量差异很大同一套参数不一定通用。测试时重点关注表格对齐、公式结构、阅读顺序这三个指标它们对最终结果的影响最大。后续扩展方面我目前在做的几个方向一是把 OCR 结果接入 RAG 系统用 Markdown 格式的文档做知识库检索效果比纯文本好很多二是用大模型做后处理把 OCR 输出的 Markdown 丢给大模型让它自动提取结构化字段比正则表达式灵活得多三是做增量处理只对文档中变化的部分重新 OCR减少重复计算。最后分享一个我踩过的小坑jina-ocr-v1 的输出里Markdown 表格的竖线对齐有时候会多一个或少一个空格导致渲染时列宽不一致。这个不影响数据但看起来不舒服。我的做法是在后处理阶段用正则表达式统一竖线两侧的空格数量让表格看起来更整齐。这个细节很小但能让输出结果更专业。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑