做 Web CAD 的同学应该都遇到过这种情况:用户上传一张 DWG,兴高采烈地点开网页,然后浏览器开始解析实体、细分几何、构建渲染数据。CPU 开始发热,内存开始上涨,风扇开始起飞。用户盯着加载动画,心里只有一个问题:
我只是想看张图,至于让我电脑干这么多活吗?
其实,如果图纸主要用于发布、分享和归档,我们完全可以换个思路:提前把图纸处理好,用户打开网页直接看,不就完了吗?
本文介绍如何利用 @mlightcad/cad-simple-viewer 和 @mlightcad/cad-html-plugin,将 DWG/DXF 预先转换成可直接部署的静态资源。
先看个实际效果:
Demo 使用的就是预渲染方案。第一次打开可能需要下载一些资源,缓存建立后,再次访问同一个页面就会快不少。
注意:Demo 部署在境外服务器,国内访问可能需要网络代理工具。
一、两种架构,区别有多大?
方案 A:用户打开,浏览器开始干活
DWG/DXF → 下载 → 解析实体 → 几何细分 → 渲染
这是 cad-viewer 默认打开 DWG/DXF 的方式。优点是拿到文件就能处理,也方便实现编辑等功能。缺点是解析和几何细分都发生在用户设备上。图纸简单还好,遇到大型图纸,低端手机可能直接进入“深度思考”模式。
方案 B:提前处理,用户直接看图
转换阶段:
DWG/DXF → 解析和细分 → 生成显示数据 → 静态资源
访问阶段:
打开网页 → 加载显示数据 → 渲染
这就像餐厅提前备菜,而不是每来一位顾客,就从种菜开始。
cad-html-plugin 的 **multi-file ACEX package(多文件包)**就是为这种场景准备的。
图纸提前完成解析和几何细分,生成一个 ZIP。解压后就是普通的静态目录,可以部署到 Nginx、对象存储或 CDN,不需要专门的后端运行时。
这种方案尤其适合:
- 图纸发布、分享和归档;
- 大量用户反复查看同一张图;
- 希望改善移动端看图体验;
- 不希望直接向浏览者提供原始 DWG/DXF。
当然,预渲染也不是万能药。显示数据需要下载,体积可能比原始图纸更大;源图纸更新后,也必须重新转换和发布。
简单来说:实时解析适合交互和编辑,预渲染适合只读发布。
二、导出的到底是什么?
解压后的目录大致如下:
my-drawing/
viewer.html
my_drawing.acex.json
chunks/
L0-000.acex.gz
L0-001.acex.gz
L0-osnap-000.osnap.gz
L1-000.acex.gz
其中:
viewer.html:包含查看器运行时的入口页面。*.acex.json:图层、布局、范围和数据块索引等信息。*.acex.gz:压缩后的几何数据。*.osnap.gz:测量和对象捕捉需要的数据。
浏览器打开页面后,先读取清单,再逐块下载、解压和渲染当前布局的数据。其他布局和对象捕捉数据可以按需加载。
所以,它不是把 DWG 转成了一张静态图片,而是生成了一个支持交互的 Web CAD 查看器。
根据导出模式,还可以支持图层管理、布局切换、测量、批注和对象捕捉等功能。
三、怎么生成多文件包?
有三种方式。
方式一:手动导出
在 cad-viewer 中打开图纸,执行 chtml 命令,选择“多文件包(ZIP)”即可。
适合偶尔导出几张图纸。如果每天要处理几百张,建议自动化。
方式二:使用 CLI 批量转换
推荐使用 @mlightcad/cad-simple-viewer-cli。
它基于 Playwright,在无头 Chromium 中执行解析、几何细分和导出流程,适合接入服务端转换任务或 CI。
安装:
npm install -D @mlightcad/cad-simple-viewer-cli
npx playwright install chromium
需要 Node.js 20 或更高版本。
CLI 自带导出脚本 examples/export-html-multi.scr,内容如下:
-chtml
Multi
Yes
Yes
Extents
Measure
quit
导出一张图纸:
cad-simple-viewer-cli \
-i ./drawings/floor-plan.dwg \
-s node_modules/@mlightcad/cad-simple-viewer-cli/examples/export-html-multi.scr \
-o ./out
成功后会生成 floor-plan.zip。
接下来就可以自动解压、发布到服务器,再把 viewer.html 的链接发给用户。
方式三:在自己的 Web 应用中集成
如果你的产品已经嵌入了 cad-simple-viewer,也可以直接调用导出 API:
import { AcApHtmlConvertor } from '@mlightcad/cad-html-plugin'
await new AcApHtmlConvertor({
viewerRuntimeUrl: './viewer-runtime.iife.js'
}).convert('floor-plan.dwg', {
exportFormat: 'multi',
viewerMode: 'measure',
exportLayouts: true,
exportInvisibleLayers: true,
initialView: 'fit'
})
如果用户只需要浏览,可以将 viewerMode 设为 view,减少不必要的功能和数据。
另外,cad-html-plugin 还提供 buildAcExPackage() 等底层 API,可以直接生成文件集合,省去 ZIP 打包和解压步骤,方便上传对象存储。
需要注意:服务端自动转换建议使用 CLI;直接调用导出 API 更适合集成到已有的 Web CAD 应用中。
四、部署时有个坑,千万别踩
解压后,把整个目录部署到 Nginx、Apache 或对象存储即可。用户访问:
https://你的域名/cad-packages/floor-plan/viewer.html
不过有一个问题特别容易让人排查半天。
不要让服务器自动解压 .acex.gz 和 .osnap.gz 文件!
这些文件已经经过 gzip 压缩,查看器会在 JavaScript 中自行解压。如果服务器又添加了:
Content-Encoding: gzip
浏览器可能会先自动解压一次,查看器再解压一次,最后直接报错。服务器应该将这些文件作为原始二进制数据返回,例如:
Content-Type: application/octet-stream
另外,当前加载器要求页面、清单和数据块同源,因此最好把整个包放在同一个站点或 CDN 域名下。本地测试也很简单,在解压目录执行:
npx serve .
然后访问 http://localhost:3000/viewer.html。如果图纸能够正常显示,基本就说明部署配置没问题。
五、总结:让用户少等一会儿,其实不难
利用 @mlightcad/cad-simple-viewer 和 @mlightcad/cad-html-plugin,可以把 DWG/DXF 的解析和几何细分提前完成,再将结果作为静态资源部署。这样做有几个好处:
- 图纸只需转换一次,后续用户直接加载显示数据;
- 可以部署到 CDN,降低重复计算和服务端运行成本;
- 支持分块加载,不必等所有几何数据下载完才开始显示;
- 保留图层、布局、测量和批注等交互能力。
当然,如果需要在线编辑、实时协同,预渲染就不一定合适;如果图纸只读发布、反复分享,它则是一个值得考虑的方案。技术选型没有银弹,只有合不合适。