不把源图纸交给对方,不绑云端账号,不装 AutoCAD ------ 一个浏览器、一个文件,照样能缩放、切图层、量距离。
写在前面
传统分享 CAD 图纸有两个选择:直接发 DWG/DXF 文件,安全性堪忧;或者转 PDF,看着方便但几乎不能动手操作。这个"单文件离线全功能 HTML 查看器"就是个折中又聪明的办法------既安全又好用,还能保持 CAD 的大部分操作体验。
核心妙处很简单:把图纸数据和浏览器运行的工具全打包在一个 HTML 文件里,收件人无需安装 AutoCAD,也不用联网。你发出去的文件就像装了隐形盾牌,数据安全牢靠,不怕外泄。更棒的是,用户还能平移、缩放、测量,甚至切换图层,就像在 AutoCAD 里探险一样,但不能修改原图,让设计者的成果稳如老狗。
这样一来,分享 CAD 图纸就像发一张"万能浏览卡":谁收到都能看、测量、讨论,但绝对不能乱改。对于跨团队、跨公司合作特别友好------安全、省心,还省去软件安装的麻烦。
总结一句话:这玩意儿让 CAD 图纸既"安全护身",又"随手可玩",让你在不丢灵魂(和版权)的情况下,轻松分享、讨论和展示设计成果。

Demo :mlightcad.github.io/cad-viewer/...
1. 背景:交图纸的「第四种打开方式」
做项目的人几乎都经历过这一幕:图要给对方看,方式却总在 泄密、难用、离不开网 之间三选一。
1.1 三条老路,三条老坑
| 你怎么交 | 对方得到的 | 真实体验 |
|---|---|---|
| 直接发 DXF / DWG | 完整图纸数据 | 对方能打开、能改、能拷 ------ 图层、块、属性、你没画出来的东西也可能都在里面。保密是最大雷区。 往往还得装一套 CAD。 |
| 导出 PDF | 一张「死」图 | 发邮件、打印都省心,但 CAD 的灵魂没了:不好按图层开关、不好缩到某一类对象、量尺寸也别扭。适合「看一眼」,不适合「对着图干活」。 |
| 云端看图 / 分享链接 | 浏览器里的在线预览 | 图纸上了别人的服务器 ------ 合规、审计、客户保密协议 先过一遍脑。对方还得 一直联网;工地地下室、飞机上、客户内网隔离?链接还可能过期。 |
1.2 第四条路:一个 HTML,自带「迷你 CAD 看图」
导出 HTML 是 cad-viewer 非常 unique 的招牌能力(业内少见,我们认真做的那种):
- 不给源文件 :HTML 里只有 显示用几何快照(顶点、颜色、图层表),不是 DWG/DXF,对方没法还原成可编辑源图,泄露面小一大截。
- 不像 PDF 那么「呆」 :离线就能 范围缩放、拖拽平移、图层显隐、缩放到图层、两点测距,中英文界面还能切 ------ 真·看图工作流。
- 不绑云端 :生成 单个
.html,脚本内联进去,U 盘、file://、内网静态页都能开,断网照样用。 - 交付极简 :微信、邮件、网盘丢一个文件;对方只要有现代浏览器,零安装、零注册。
一句话定位:在「保密、离线、好用」三角里找平衡点 ------ 不是替代 AutoCAD,而是「把该看的图,安全、体面地送到对方屏幕上」。
下面开始拆引擎盖:这套东西在代码里长什么样。
2. 设计目标与边界
2.1 我们想要什么
| 目标 | 人话版 |
|---|---|
| 离线单文件 | 一个 .html 搞定,不依赖后端,也不再把 DWG/DXF 塞进去 |
| 体积可控 | 只带「画出来长什么样」的批数据,不带整库实体 |
| 两趟班车 | 导出在完整 Viewer 里干;查看在轻量 Runtime 里干,各干各的 |
| 好维护 | 类型、编解码、收集、打包、UI 分文件;公开 API 统一 AcEx 前缀 |
2.2 我们刻意不做什么
- 不在 HTML 里复活可编辑的
AcDb实体 - 不让离线页再去解析 DXF/DWG
- 不指望它替代完整 Viewer 的 Ribbon、命令行、属性面板
2.3 两趟班车:导出 vs 查看
- 班车 A :在
cad-viewer/cad-simple-viewer里打开图,跑chtml,把当前场景收成快照,再打包进 HTML。 - 班车 B:对方双击 HTML,内联脚本解压快照、搭 Three.js 场景,开始缩放图层量距离。
3. 在 CAD-Viewer 里导出
如果你已经用上了 @mlightcad/cad-viewer 模块,按这个来:
3.1 三步走,不用献祭
- 先把图打开 ------ DWG/DXF 随便,等线都画出来、别还一片黑。
- 喊导出 ------ 任选其一:
- Ribbon / 主菜单里找 Export HTML (源码在
MlRibbonCommands.vue、MlMainMenu.vue,迷路别找我)。 - 命令行敲
chtml(跟sendStringToExecute('chtml')是一回事,键盘党友好)。
- Ribbon / 主菜单里找 Export HTML (源码在
- 等转圈结束 ------ 浏览器会下载
xxx.html。名字多半跟图纸走,扩展名铁定是.html,不会突然变成.exe(那就离谱了)。
3.2 导出前默念三句
| 事项 | 人话 |
|---|---|
| 图得真打开 | 导出的是屏幕上已经画出来的,不是「我猜你 C 盘 有个文件」 |
| 图层别装死 | 冻住/关掉的层,快照里就当它们不存在 |
| 语言会打包 | 导出时 Viewer 啥语言,离线页默认就跟啥;想英文界面就先切英文 |
| 第一次集成 | 得把 viewer-runtime.iife.js 安顿到静态资源里,见 [第 6 章](#事项 人话 图得真打开 导出的是屏幕上已经画出来的,不是「我猜你 C 盘 有个文件」 图层别装死 冻住/关掉的层,快照里就当它们不存在 语言会打包 导出时 Viewer 啥语言,离线页默认就跟啥;想英文界面就先切英文 第一次集成 得把 viewer-runtime.iife.js 安顿到静态资源里,见 第 6 章,否则导出会跟你抱怨找不到 runtime "#6-%E9%9B%86%E6%88%90%E5%88%B0%E8%87%AA%E5%B7%B1%E7%9A%84%E5%BA%94%E7%94%A8"),否则导出会跟你抱怨找不到 runtime |
4. 用命令行导出 DXF / DWG
不爱点界面、偏爱黑框和光标闪烁?@mlightcad/cad-html-exporter-cli 奉陪 ------ 背后 Playwright 开着 Chromium 偷偷干和浏览器里一样的活,你只是看不见而已。
4.1 第一次:请浏览器吃个安装包
bash
pnpm install
pnpm export:html:setup # 装 Chromium,就一回,别跳过
4.2 根目录三条咒语(试用首选)
| 咒语 | 干啥 |
|---|---|
pnpm export:html |
build CLI + 用样例 minimal-line.dxf 吐出 tmp/minimal-line.html |
pnpm export:html:run -- <输入> -o <输出> |
已 build 过?直接对你自己的图下手 |
pnpm export:html:setup |
上面那条装浏览器,忘了就再来 |
摸鱼试用:
bash
pnpm export:html
# 浏览器打开 tmp/minimal-line.html,跟同事吹「看,一条线也能离线」
对自己的图动刀:
bash
pnpm export:html:run -- D:\drawings\plan.dwg -o D:\out\plan.html
pnpm export:html:run -- drawing.dxf -o drawing.html --locale zh --title "一层平面图"
4.3 在包目录里念咒
bash
pnpm --filter @mlightcad/cad-html-exporter-cli build
pnpm exec cad-html-exporter path/to/file.dxf -o out/viewer.html
4.4 参数表(背不下来就翻)
| 参数 | 说明 |
|---|---|
<input> |
必填,.dxf 或 .dwg,别的扩展名会被拒 |
-o, --output |
输出路径;不写就「同名换 .html」,懒人友好 |
--locale |
en / zh 等,嵌进离线页 |
--title |
窗口标题 / 元数据,显得专业 |
4.5 命令行碎碎念
- Node ≥ 20;第一次要联网(Chromium + 字体 CDN,和示例 Viewer 同款)。
export:html会顺手 build;只跑export:html:run的话,记得先 build 过至少一次。- 大图导出慢是正常的 ------ 别狂按 Ctrl+C,Chromium 也会委屈。
更啰嗦的见 packages/cad-html-exporter-cli/README.md。
5. 打开并使用导出的 HTML
5.1 怎么开
| 姿势 | 做法 |
|---|---|
| 本机土豪 | 双击,或拖进 Chrome / Edge / Firefox |
| 服务器土豪 | 扔静态站,甩 URL |
file:// |
行;浏览器偶尔唠叨两句安全提示,一般无视即可 |
不必 装 CAD、不必装 Node、不必 旁边再蹲一个 viewer-runtime.iife.js ------ 都焊在 HTML 里了。
5.2 左边那一排按钮
| 按钮 | 干啥 |
|---|---|
| 范围缩放 | 一眼看全图,省得滚轮搓出火星 |
| 测距 | 点两下出距离;再点或换模式收工 |
| 图层 | 抽屉拉开,勾选人生 |
| 语言 | 中英切换,localStorage 帮你记 |
5.3 图层面板
- 勾选 = 显隐;「全显 / 全隐」拯救图层太多的绝望。
- 缩放到图层:只盯这一层;层里没东西?按钮会灰,不骗你点。
- 手机窄屏时抽屉会自觉靠边,尽量不挡你的图(旧 HTML 挡屏?重新导一版)。
5.4 测量
数字跟导出时图纸单位走。小数位怪怪的?回去在 导出前 把原图打开看清楚 ------ 别怪 HTML,它只是个诚实的显示器。导出为 HTML 后的页面中的测量功能还在进一步完善中,目前只支持距离测量。
6. 集成到自己的应用
要把「导出 HTML」塞进自家产品的前端同学,坐稳了。
6.1 你需要的
- 依赖:
@mlightcad/cad-simple-viewer(里头已经勾着@mlightcad/cad-html-exporter)。 - 用户命令:
chtml(AcApExportHtmlCmd→AcApHtmlConvertor,名字拗口但好用)。
6.2 别忘了 Viewer Runtime(不然导出会哭)
导出时会去 fetch viewer-runtime.iife.js 全文,再 焊进 HTML。默认找:
text
./viewer-runtime.iife.js
MlCadViewer / AcApDocManager.createInstance 可改:
ts
htmlViewerRuntimeUrl?: string | URL // 比如 './assets/viewer-runtime.iife.js'
集成 checklist(打勾再上线,省得半夜被叫起来):
pnpm --filter @mlightcad/cad-html-exporter build- 把
packages/cad-html-exporter/dist/viewer-runtime.iife.js拷到静态目录,路径和htmlViewerRuntimeUrl对得上。 - 开发/发布时这个 URL 真能访问(Vite 拷贝插件是你的好朋友)。
- 改了 exporter 或 Runtime?旧 HTML 不会自己进化,请让用户重新导。
抄作业:cad-simple-viewer-example / cad-viewer-example 的 vite.config.ts 里 vite-plugin-static-copy。
6.3 已有快照只想打包(大佬玩法)
手里已经有 AcExSnapshotV1?AcApHtmlConvertor.packSnapshot() 或裸调 packHtml(snapshot, { viewerRuntime }),跳过场景收集,直接装箱。
7. 常见问题
| 你看到的鬼样子 | 八成是 | 咋办 |
|---|---|---|
| 找不到 runtime | 没 build 或路径飘了 | build exporter;对 htmlViewerRuntimeUrl |
| 工具栏只剩一行英文、图标蒸发 | 旧 HTML 或 i18n 把按钮文案「一锅端」了 | 重新导出 ;当前版已用 data-i18n-text 保命 |
| 打开白屏 | 快照烂了或 Runtime 没焊牢 | F12 看控制台;HTML 里应有两坨大 <script> |
file:// 唠叨安全 |
浏览器的职业病 | 通常继续;确认是完整单文件 |
| CLI 喊 Chromium | 没装 Playwright 浏览器 | pnpm export:html:setup |
| CLI「Failed to open」 | 坏文件、扩展名不对、worker 没 build | 认准 .dxf/.dwg;先 build CLI |
| 手机图层挡屏 | 上古 CSS | 重新导出,新时代了 |
| 测量小数位离谱 | 原图单位/精度 | 导出前在 Viewer 里把图看明白 |
8. 原理与实现(开发者一章)
日常用法上面够了;下面给要拆发动机的人。一章讲完,不拆成九堂微课。
8.1 背景:交图的「第四条路」
| 老办法 | 槽点 |
|---|---|
| 直接发 DWG/DXF | 泄密像开闸,对方还得装 CAD |
| 好看难用,图层?测量?下次一定 | |
| 云端链接 | 要网、要账号、合规邮件警告 |
HTML 导出:单文件、不带源格式、能切层能测距 ------ 在「保密、离线、好用」三角里找个能坐的位子。不是 AutoCAD 杀手,是「体面地把图送到对方屏幕上」。
9.2 设计边界
干: 离线单文件、只带显示几何、导出/查看两班车、AcEx 前缀统一。
不干: HTML 里改实体、离线再解析 DXF/DWG、顶替完整 Viewer ------ 各玩各的赛道。
9.3 包分工
| 包 | 干啥 |
|---|---|
cad-html-exporter |
快照、压缩、抠几何、packHtml、壳、Runtime |
cad-simple-viewer |
chtml、Builder、Convertor |
cad-viewer |
Ribbon、htmlViewerRuntimeUrl |
cad-html-exporter-cli |
Node + Playwright 批处理 |
three-renderer |
批对象类型,供收集器认亲 |
产物重点:dist/viewer-runtime.iife.js ------ 导出时要 fetch 来内联的那坨。
9.4 数据流(应用内)
CLI:Playwright 打开 dist-runner → exportCadToHtml() → 同一套 Builder + packHtml → 写盘。
9.5 技术要点
- 快照
AcExSnapshotV1:meta、图层表、布局+批、当前布局 id。 - 塞进 HTML :gzip + Base64 躺在
<script id="mlcad-snapshot">;内联 JS 前把</script>转义,不然 HTML 会提前「剧终」。 - 收集 :DFS 场景树,揪
AcTrBatchedLine/AcTrBatchedMesh。 - Runtime:解码 → i18n → WebGL → 按层 Group。
- i18n 血泪史 :别对装着按钮的爹节点
textContent = ...,用data-i18n-text那套,否则工具栏变单行公告栏。