先说一个我实际碰到的场景:芯片厂内部的工艺文档系统升级,工艺部门提了一个需求,要求工程师在 TinyMCE 里贴 CAD 图纸时,保存后放大看依然要清晰,放大多少倍线宽和标注都不能虚。最初很多人觉得这不就是截图吗,等真正做了才发现,CAD 的 Ctrl+C 和网页的 Ctrl+V 根本不在一个语言体系里。这篇文章围绕这个场景,把 CAD 图纸如何才能以矢量格式进入 TinyMCE 的完整思路、代码和踩坑记录都摊开来聊。如果你是芯片制造企业的系统工程师、知识库负责人,或者正在被“富文本编辑器贴大图变糊”困扰,这篇应该能给你几条能直接落地的路线。
1. 需求场景拆解:芯片厂的知识库为什么非要矢量 CAD 不可
1.1 哪些人真的需要在 TinyMCE 里贴 CAD 图纸
很多做 Web 应用的人第一次听到这个需求会觉得奇怪,一个基于浏览器的富文本编辑器,为什么要处理 CAD 这种专业格式?但放到芯片制造企业内部就特别合理。晶圆厂、封装厂里面存在大量过程文档、质量评审、变更申请单、设备维护记录,底层都是一个带富文本编辑框的业务系统。TinyMCE 因为集成简单、插件成熟,在不少企业的知识库、QMS、PLM 配套系统中都是首选编辑器。
真正会在编辑器里粘贴 CAD 图纸的人,通常不是图形工程师,而是工艺整合工程师、设备工程师、质量工程师。他们手里有掩模版图、封装基板的走线布局、厂务改造的管线图,甚至光刻区域的黄光机台布局图。写评审意见时,需要用图纸把问题位置圈出来;出变更单时,要引用当前版本的版图;做故障复盘时,还要把 SEM 照片和对应的 CAD 区域放在同一份报告里。对这些用户来说,最顺畅的操作就是“截图下来再贴”的反面:希望把 CAD 直接贴进 TinyMCE,保留可放大、可检索、可打印的矢量数据。
1.2 截图粘贴为什么不行:精度、缩放和追溯全在流失
用截图的方式把 CAD 图纸塞进编辑器,单看操作确实快。但图纸不是普通照片,芯片制造场景下,图纸里的信息密度高到离谱。一个掩模版图可以有几万条多边形和孔洞,一段金属走线的宽度在源文件里是带精确小数位的数值,截图之后这些信息直接变成像素颜色块。系统里存档的图纸如果是一张静态图片,未来有人拿放大镜去核对线宽和间距,根本无从下手。
更麻烦的是,网页编辑器对图片默认会压缩或者限制尺寸。工程师明明贴了一张 4000 像素宽的截图,保存后再打开发现被编辑器样式表缩成 800 像素,标注文字糊成一团。这种问题在评审追溯场景里非常致命。图纸本身是变更记录的附件,如果清晰度不达标,后续审计举证时就会怀疑所贴图纸是否真实反映了当时的设计状态。所以企业内部的要求很清楚:粘贴进 TinyMCE 的内容,必须保留矢量语义,至少保证任何缩放级别下边界和文字都可读。
1.3 “粘贴”两个字背后其实是三套数据链路的协同
要实现真正的 CAD 粘贴矢量输出,要处理的不是 TinyMCE 一个问题,而是 CAD 客户端、浏览器编辑器、服务器存储三端的协同。CAD 端负责导出什么样的剪贴板格式;浏览器端决定要不要拦截、能不能接受 SVG 等矢量介质;服务器端则需要把 CAD 原生的 DWG、DXF 转换成 Web 能识别的 SVG,或者干脆维护一份轻量化预览文件。
我一开始也天真地认为 TinyMCE 的 PowerPaste 插件开了 paste_data_images 就能解决,结果试下来发现它只能识别位图 PNG 和 JPEG。方向就必须从「让编辑器直接读懂 CAD」改成「在粘贴路径里插入一个转换层」。理解了这一点,后面很多问题就顺了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 剪贴板数据分析:CAD 复制后粘贴到网页,到底发生了什么
2.1 CAD 客户端把哪些格式放进了剪贴板
先从 Windows 剪贴板的底层讲起。AutoCAD 等主流 CAD 软件里选中图形按 Ctrl+C,系统并不会只放一张图片,而是会同时注册多个格式。至少会有设备无关位图(DIB)、增强型图元文件(EMF),如果复制来源是 AutoCAD,它还会放一份私有格式数据,方便你再次粘贴回 AutoCAD 时保持对象属性。此外,某些情况下还会带文本描述、文件路径等辅助信息。
这里面的 EMF 值得一提,它本质是一套矢量绘制指令,在 Word、PowerPoint 里粘贴时是能保持矢量效果的。问题在于浏览器端对 EMF 几乎没有原生支持,Chrome、Edge 的 paste 事件拿到剪贴板项目后,通常只能看到 text/plain、text/html、image/png 这三种通用格式。换句话说,CAD 放了很多好东西进来,但浏览器只愿意把位图递给你,矢量数据被挡在门外。
| 剪贴板格式 | CAD 是否输出 | Windows 原生软件支持 | 浏览器粘贴事件支持 |
|---|---|---|---|
| DIB/Bitmap | 是 | 全支持 | 支持,但为位图 |
| EMF | 是 | Word/PPT 等支持 | 不支持 |
| DXF/DWG 私有格式 | 是 | 仅 CAD 再粘贴 | 不支持 |
| SVG File 格式 | 依赖生成方式 | 部分支持 | 支持但少见 |
2.2 TinyMCE 的粘贴回调到底能拿到什么
TinyMCE 的粘贴流程,本质上是将浏览器吐出来的 ClipboardEvent 数据做二次处理。默认的 paste 插件能从 clipboardData 里读取纯文本和 HTML;如果配置了 paste_data_images: true,它可以把位图图片转成 base64 后插入编辑器。PowerPaste 商业插件则增加了很多从 Word、Excel 复制内容的保真清理逻辑。但不管哪个插件,都没有能力把 CAD 放在剪贴板里的 EMF 或私有格式读出来变现。
如果你想在粘贴事件里加自己的判断,通常的代码切入点是 paste_preprocess 和 paste_postprocess 钩子。前者拿到的是即将插入编辑器的字符串,适合替换内容;后者拿到的是一个 DOM 节点,适合做安全性清理。如果拿到 clipboardData.items,里面可能会有一个 image/png 的 File 对象,或者当用户从 SVG 编辑器复制时,会有 image/svg+xml 类型。不要指望它给你 DWG 文件,浏览器不会给你的。
2.3 矢量输出要跨过的三道坎
第一道坎是格式鸿沟。CAD 的 DWG 是闭源二进制格式,DXF 虽然有公开规范,但也包含大量图元类型和扩展数据,不可能直接在浏览器里解析。要让图纸进入 Web 世界,得先转换成 SVG、PDF、Canvas 能识别的中间格式。
第二道坎是剪贴板形态。即便是 DXF 这种文本化格式,CAD 也不会默认把整个 DXF 塞进剪贴板;图纸的完整数据依然躺在文件系统里。用户在做普通复制粘贴时,剪贴板里只有显示用的位图或 EMF,矢量源头从来不在剪贴板上,而在源文件里。
第三道坎是编辑器安全策略。SVG 本身可以放 <script>,TinyMCE 默认的 valid_elements 配置通常不会放行裸 SVG,即使粘贴进来也会被过滤掉大量属性,导致图形显示异常。矢量输出方案必须同时解决转换、注入、清洗三件事,只解决其中任何一个都不完整。
3. 方案选型:把 CAD 图纸做成可粘贴的矢量,有哪几条路
3.1 方案 A:CAD 端先导出 SVG,再以图片或文件方式插入
这是最成熟的交付型方案。工程师在 CAD 里把需要分享的区域用窗口选择选好,然后执行打印或者导出命令。推荐做法是先在 CAD 里输出 PDF,再用 PDF 转 SVG 工具生成矢量图,因为 CAD 直接转 SVG 的工具往往在文字、填充和线型上容易失真,而 PDF 是 CAD 最完善的中间格式。
转换完成后,SVG 可以有两种进入 TinyMCE 的姿势。一种是把 SVG 文件上传到系统的文档附件区,再用编辑器插入附件链接,同时把 SVG 第一帧渲染成一张预览图放进正文;另一种是把 SVG 转成 data URI 当图片插入。前者利于检索和二次下载,后者更像内容的一部分。对于需要频繁引用图纸的评审流程,我更推荐前者,因为保存到附件区后可以再用其他工具做格式转换,不会把数据锁死在编辑器的 HTML 里。
这个方案的缺点是它不算严格意义上的“粘贴”,更像“导出后上传”。但胜在实现简单、可控性好。如果企业已经有图纸管理系统,完全可以在 CAD 工具栏里加一个“发布到知识库”按钮,由插件执行导出和上传动作。
3.2 方案 B:在粘贴事件里拦截位图,自动触发转换服务
如果你就是想让用户保留 Ctrl+C、Ctrl+V 的习惯,那就需要在 TinyMCE 初始化后监听原生的 Paste 事件。当检测到剪贴板里只有 PNG 或者没有 SVG 时,不要直接使用位图,而是弹窗提示用户上传源文件,或者从 CAD 安装目录读取上一次导出的文件进行转换。这里比较实用的设计是做一个“识别剪贴板里有没有 CAD 特征数据”的逻辑,比如从 text/html 片段里查找 CAD 软件的痕迹,或者让用户在 CAD 里先通过插件生成一个 SVG 文件放入剪贴板。
实际项目中,我见过一种很顺滑的做法:在 CAD 里装一个小插件,把用户选中的图形直接写成 SVG 文件,然后通过本地 WebSocket 服务把文件的 base64 内容发给前端页面。TinyMCE 前端收到这个 SVG 后自动插入编辑器。整个过程用户感知就是“我从 CAD 复制,到网页里粘贴”,实际上剪贴板只承担了一个触发信号的作用,真正的数据是通过本地回环网络传的。这个方案在受控的内网环境里很稳定,但对 CAD 终端和浏览器的联动要求较高。
3.3 方案 C:不粘贴原图,改为嵌入 Web CAD Viewer 对象
还有一个思路是放弃“粘贴这张图”的表象,直接在 TinyMCE 里嵌入一个可交互的 Web CAD Viewer。使用组件或 iframe 嵌入,加载的是 DXF/DWG 原始文件,页面内可以平移、缩放、显隐图层。TinyMCE 在这里只负责承载一段自定义 HTML,真正的渲染由旁路的 Viewer 完成。
这个方案最大优势是矢量精度零损耗,而且还能保留图层关系,这对多层光刻图形特别有价值。但它有几个代价:一是 TinyMCE 是全屏编辑模式,嵌入 Viewer 无法和文章正文滚动无缝联动,体验会割裂;二是 Viewer 依赖大量 JavaScript,打印导出 PDF 时会被漏掉;三是性能受模型大小影响严重,几十 MB 的图纸放进编辑器正文里,每次打开文档都是灾难。
所以我的建议是:方案 C 适合“单独建图档审阅记录”的场景,不适合把 CAD 混在普通技术文档里。如果目标是让 CAD 作为正文里一块可读图区,方案 A 和 B 的组合最合适。
3.4 三条路线的综合对比
| 维度 | 方案 A(导出转 SVG) | 方案 B(粘贴事件拦截) | 方案 C(Web Viewer) |
|---|---|---|---|
| 用户操作成本 | 中,需导出再上传 | 低,接近原生复制粘贴 | 低,但需单独页面 |
| 矢量保真度 | 高 | 高 | 极高 |
| 图层/属性保留 | 可部分保留 | 可部分保留 | 完整保留 |
| 与正文混排能力 | 好 | 好 | 差 |
| 开发工作量 | 较低 | 较高 | 高 |
| 是否适合芯片厂评审文档 | 适合 | 适合 | 仅适合专项审图 |
芯片制造企业内部最常见的是“工艺变更单”里需要贴一小块版图作为差异示意,这种场景用方案 A 就已经够了。真正需要方案 C 的场景是版图设计评审、掩模缺陷分析这类的专题页,不应该硬塞在 TinyMCE 里。
4. TinyMCE 配置与代码落地细节
4.1 编辑器基础配置:先让 SVG 合法进入文档
无论走哪条路线,最终 TinyMCE 的 init 配置里都要处理 SVG 是否放行的问题。这里给一个我在内网项目里实测可用的精简配置。需要说明,同样的配置在 TinyMCE 5 和 6 里基本通用,个别插件的名称差异以官方文档为准。
javascript复制tinymce.init({
selector: '#articleEditor',
plugins: 'paste code lists image link',
toolbar: 'undo redo | formatselect | bold italic forecolor | bullist numlist | link image',
paste_data_images: true,
extended_valid_elements: [
'svg[*]',
'defs[*]',
'g[*]',
'symbol[*]',
'use[*]',
'path[*]',
'polygon[*]',
'polyline[*]',
'circle[*]',
'ellipse[*]',
'rect[*]',
'line[*]',
'text[*]',
'tspan[*]',
'marker[*]',
'title[*]',
'desc[*]'
].join(','),
content_style: 'svg { max-width: 100%; height: auto; }'
});
extended_valid_elements 的作用是告诉 TinyMCE,哪些标签和属性在粘贴时需要保留。如果不加这一行,内联 SVG 就算被粘贴进来,也会被编辑器的净化规则拆得只剩 <svg></svg> 空壳。另外一个很关键的细节是 content_style 里要写 svg { max-width: 100%; },否则有的浏览器会把 SVG 的默认宽度撑得非常大,破坏文章排版。
4.2 粘贴后的 SVG 安全清洗,别把脚本带进来
让 SVG 合法显示不代表要让它肆无忌惮。SVG 和 HTML 一样能携带 <script> 和事件属性,比如 <path onclick="...">,如果粘贴来源被污染,就可能产生存储型 XSS。我的做法是在 paste_postprocess 里做一次强制清洗,所有动态插入的 SVG 都必须过这个函数。
javascript复制function sanitizeSvg(root) {
if (!root) return;
const svgList = root.querySelectorAll('svg');
svgList.forEach((svg) => {
// 删除脚本、外链和危险容器
svg.querySelectorAll('script, foreignObject, iframe, object, embed').forEach((el) => el.remove());
// 删除所有事件绑定属性
svg.querySelectorAll('*').forEach((el) => {
[...el.attributes].forEach((attr) => {
if (attr.name.toLowerCase().startsWith('on')) {
el.removeAttribute(attr.name);
}
});
});
// 防止外部资源加载,只保留纯图形内部引用
svg.querySelectorAll('*').forEach((el) => {
[...el.attributes].forEach((attr) => {
const value = attr.value.trim().toLowerCase();
if (attr.name === 'href' && (value.startsWith('http:') || value.startsWith('https:') || value.startsWith('//'))) {
el.removeAttribute(attr.name);
}
});
});
// 补充 viewBox,避免某些 CAD 转换工具漏写
if (!svg.getAttribute('viewBox') && svg.getAttribute('width') && svg.getAttribute('height')) {
svg.setAttribute('viewBox', `0 0 ${svg.getAttribute('width')} ${svg.getAttribute('height')}`);
}
});
}
tinymce.init({
// ... 省略其他配置
paste_postprocess: function(editor, args) {
sanitizeSvg(args.node);
}
});
清洗思路其实就三条:事件必须清除、外部资源必须掐断、图形显示属性必须补全。很多开发只关心“能不能显示”,忽略了编辑器保存的内容会被无数人打开,一旦出安全问题,损失比图纸精度大得多。
4.3 读取剪贴板里的 SVG 文件并自动插入
这一步解决的是用户从 SVG 编辑器或者 CAD 转换插件里复制场景。当剪贴板里有 image/svg+xml 类型的文件时,你可以在 TinyMCE 的 Paste 事件前置拦截,取到 File 对象后转成 data URI 插入编辑器。
javascript复制editor.on('Paste', function(e) {
const clipboardData = e.clipboardData || window.clipboardData;
if (!clipboardData) return;
for (const item of clipboardData.items) {
if (item.type === 'image/svg+xml') {
const file = item.getAsFile();
if (!file) return;
e.preventDefault();
const reader = new FileReader();
reader.onload = function(evt) {
const dataUri = evt.currentTarget.result;
editor.insertContent(`<img style="max-width:100%;" src="${dataUri}" alt="CAD SVG" />`);
};
reader.readAsDataURL(file);
break;
}
}
});
这里有个设计取舍:我明明要求矢量输出,为什么最后插入的是 <img> 而不是内联 SVG?原因是位图方式把 SVG 用 data URI 包起来后,编辑器内部不会再对图形节点做任何净化,脚本无法执行,安全性更高。而且浏览器渲染 <img> 里的 SVG 时依然会按矢量方式绘制,放大不会马赛克。只有当你需要用户在文档里直接双击编辑 SVG 节点,或者需要做文字检索时,才必须改成真正内联 SVG。
4.4 服务端批量转换服务:DWG/DXF 如何变成 SVG
客户端只能处理已有 SVG 文件的情况,更常见的来源还是 DWG 和 DXF。对于 DXF,可以用 Python 的 ezdxf 库做无头转换;对于 DWG,因为没有完全开源可靠的解析内核,最稳妥的方式是先用 ODA File Converter 或 CAD 的批处理打印转成 DXF/PDF,再进 SVG。下面给一个基于 FastAPI 的转换接口示例,核心思路清晰即可。
python复制import os
import subprocess
import tempfile
from fastapi import FastAPI, UploadFile
from fastapi.responses import Response
app = FastAPI()
@app.post("/api/v1/cad-to-svg")
async def cad_to_svg(file: UploadFile):
suffix = os.path.splitext(file.filename or "")[1].lower()
if suffix not in (".dxf", ".dwg", ".pdf"):
return Response("Unsupported format", status_code=400)
with tempfile.TemporaryDirectory() as tmp:
source_path = os.path.join(tmp, "input" + suffix)
content = await file.read()
with open(source_path, "wb") as fp:
fp.write(content)
svg_path = os.path.join(tmp, "output.svg")
if suffix == ".pdf":
subprocess.run(["pdftocairo", "-svg", source_path, svg_path], check=True)
else:
# 生产环境建议:先调用 CAD 命令行把 dwg/dxf 打印成 pdf
# 再走同一套 pdftocairo;这里以转换链路示意为主
subprocess.run(["dwg2dxf", source_path, os.path.join(tmp, "input.dxf")], check=True)
subprocess.run(["dsvg", os.path.join(tmp, "input.dxf"), svg_path], check=True)
# 上面的 dsvg 不是通用命令,真实项目中需替换为
# ezdxf 或 CAD 内核提供的输出脚本
with open(svg_path, "rb") as fp:
svg_data = fp.read()
return Response(content=svg_data, media_type="image/svg+xml")
这里我必须说实话,代码里注释为示意的那两行命令,实际部署时往往会换成企业内部二次开发的 CAD 批处理程序。为什么?因为 DWG 转 PDF 涉及到字体文件、打印样式、线宽映射,通用开源工具很难 100% 还原。真正的生产链路建议是这样的:CAD 软件本身安装好打印配置文件,工程师在客户端点“发布到系统”,CAD 用后台模式打开图纸并输出 PDF,系统再调用 pdftocairo -svg 获得矢量图。
4.5 一个小而美的纯前端转换补充
如果你的图纸本来就是 DXF 且图形不算特别复杂,也可以在前端用开源解析库做转换,省掉服务器开销。dxf-parser 配合 path 绘制是个常见组合。大致过程是解析 DXF 的 LINE、LWPOLYLINE、CIRCLE、ARC、TEXT 等图元,映射成 SVG 节点。但这么做工程量比较大,线型比例、标注样式、块引用、图层状态都要手工处理。我只建议在受控的少量图元场景里用,比如要贴的是晶圆边缘的小定位标记而不是整张掩模版图。
javascript复制// 思路示意,不依赖具体库
import DXF from 'dxf-parser';
async function dxfToSvg(file) {
const text = await file.text();
const parser = new DXF();
const dxf = parser.parseSync(text);
// 遍历 dxf.entities,生成 SVG path
const paths = dxf.entities
.filter(e => e.type === 'LINE')
.map(e => `<line x1="${e.vertices[0].x}" y1="${e.vertices[0].y}" x2="${e.vertices[1].x}" y2="${e.vertices[1].y}" stroke="black" />`)
.join('');
return `<svg xmlns="http://www.w3.org/2000/svg">${paths}</svg>`;
}
这段代码只是告诉你思路,真放在系统里还需要处理坐标系翻转、颜色映射和单位换算。CAD 的默认世界坐标系 Y 轴向上,SVG 的 Y 轴向下,不做翻转,图形上下会颠倒。
5. 芯片制造场景下容易踩的坑与应对
5.1 图层、颜色和线宽在转换后全乱套
芯片图纸最典型的特点是多图层,尤其是光刻相关的图层会把不同 mask 层用不同颜色分开。从 CAD 打印成 PDF 再转 SVG 时,如果打印样式表没配置好,所有元素可能都会被渲染成同一种黑色或者同一种细线宽。这个问题在处理掩模标记、划片道图形时特别明显,因为关键就是靠不同颜色区分层的。解决办法是在 CAD 的打印设置里预先建立一套面向 SVG 导出的样式表,把图层颜色和线宽映射关系固定住,别默认用“monochrome”模式。
5.2 文字标注变成炸开的点线或者直接丢失
CAD 文件里的文字分为单行文字、多行文字和属性块,字体文件如果缺失,PDF 打印时可能会出现替代字体,到了 SVG 里就变成一堆拆散的线条,业内很多人叫“乱线转文字”问题。反过来说,有的转换工具为了让外观统一,会把文字炸开成曲线轮廓,导致 SVG 文件里不可搜索,也无法复制原文字。对芯片厂的知识检索来说,这很亏,因为很多历史图纸是靠标注关键字来搜的。方案是转换链路上尽量保留文字对象的文本内容,CAD 里用 SHX 字体的单行文字是最容易炸开的,建议打印前统一转换为 TrueType 文字,或者在转换工具里开启“文本转字符”模式。
5.3 大版图转出来的 SVG 节点数量爆炸,浏览器直接卡死
一个几万条边的版图区域转成 SVG 后,文件大小可能达到几十 MB。插入 TinyMCE 后,编辑器每次输入一个字符都可能触发一次重绘,浏览器当然顶不住。我踩过的坑是,工程师觉得很清楚的图,系统管理员觉得卡得要命。后来采取了两层措施:第一,在转换服务里做简化,删除不可见图层、合并重叠路径、去除多余的小数点精度;第二,在编辑器初始化时给 SVG 外层加懒加载容器,图片滚动到可视区域前不渲染。
5.4 内网部署和权限管理:图纸不能像网上图片那样随意外链
芯片企业的图纸基本都在内网,CAD 源文件更是核心资产。因此转换服务必须跑在内网服务器上,不能把图纸上传到任何外部转换 API。同时,SVG 本身是明文 XML,里面可能带有内部文件路径、图框里的设计者姓名、版本信息等元数据。发布到文档系统前,要做元数据清理,不然一个简单的 SVG 文件就可能泄露项目代号。批量转换脚本里我建议预留一个清洗环节,把所有 <metadata>、文件注释、扩展字典删除干净。
5.5 TinyMCE 本身的一些细节也别忽视
编辑器粘贴内容时,默认会尽量保留 Word 和浏览器复制的样式,CAD 过来的内容如果没有样式上下文,容易被套上当前段落格式。这里可以给段落配置合适的字体,比如中文用宋体,图形区域内的文本再单独处理。另一个容易忽视的是,TinyMCE 保存 HTML 时会转义大量符号,SVG 里有 <、>、引号,保存前如果做的是纯文本 sanitize,很容易把合法的路径定义转坏。务必用编辑器自带的 getContent() 接口,不要自己拼 HTML。
6. 常见问题与排查技巧实录
| 问题现象 | 可能原因 | 处理建议 |
|---|---|---|
| CAD 里 Ctrl+C 后网页直接粘贴,只能得到模糊位图 | 浏览器能获取的只有 png/bmp,EMF 被丢弃 | 引入 CAD 导出或本地插件服务,把 SVG 路径传到前端 |
| 粘贴进 TinyMCE 的 SVG 只有空白,标签被删了 | extended_valid_elements 没有配置 |
按 4.1 节配置放行 svg/path/g 等标签 |
| 图形方向上下颠倒 | DXF 坐标 Y 轴与 SVG 不一致 | 转换时做 y = height - y 翻转 |
| 文字显示成方块或炸开的点线 | 缺少字体或者 SHX 字体被替换 | 打印前统一字体为 TrueType,并在服务器装对应字库 |
| SVG 插入后撑爆页面 | 缺少 viewBox 或 width/height 过大 | 清洗函数中补 viewBox,并设置 max-width:100% |
| 粘贴后浏览器提示脚本错误 | SVG 中携带着非法转义或外部引用 | 增强 sanitizeSvg,清空 script 和所有外部 href |
| DWG 文件上传后转换失败 | 服务器没有 CAD 转换内核或版本兼容问题 | 建议先用 CAD 客户端导出 PDF,再由 PDF 转 SVG |
| 图形颜色全变成黑色,图层无法区分 | 打印样式表使用的是 monochrome | 建立独立的 SVG 导出打印样式并固定颜色映射 |
| 文档保存后再次打开,图区渲染很慢 | SVG 体量过大 | 转出前图形简化,编辑器中使用懒加载容器 |
| 粘贴时总带上 CAD 里看不见的图框和批注区域 | 选择了模型空间全部对象或错误打印窗口 | 粘贴前先在 CAD 中只选目标区域,或使用窗口发布模式 |
最后说一个运维层面的经验:不要把这个转换链路的失败做成静默的。第一次上线时,我们遇到某版本 DXF 转换后 SVG 是空的,但接口返回 200,结果用户保存了半天空文档,评审会前才发现图纸没贴进去。后来所有转换接口都加了文件大小校验和最小元素数校验,转换结果小于一定阈值就直接报错并提示用户走人工处理流程。这套机制虽然不能解决所有异常,但至少能让问题在当天暴露,而不是等归档审计时才发现历史文档里大面积缺图。
