文件操作
大约 4 分钟
文件操作
打开、保存、导入导出图纸的完整 API 指南。
概览
WebCAD 支持多种文件操作方式:
| 操作 | 命令方式 | API 方式 |
|---|---|---|
| 从服务端打开 | OPENFROMSERVER | DrawingManagerService.openDrawing() |
| 保存到服务端 | SAVESERVER | DrawingManagerService.saveDrawing() |
| 从本地缓存打开 | OPENFROMLOCAL | localService.loadDrawingById() |
| 保存到本地缓存 | SAVELOCAL | localService.saveDrawing() |
| 导入 DWG | IMPORTDWG | service.uploadMap() + openDrawing() |
| 导出 DWG | EXPORTDWG | service.exportDwg() |
| 导出 PNG 图片 | EXPORTPNG | exportEntitiesToImageAndDownload() |
| 快速保存 | QSAVE | 下载 .webcad 文件 |
| 另存为 | SAVEAS | 下载 .webcad 文件 |
命令方式(简单场景)
const { Engine } = vjcad;
// 从服务端打开(弹出图纸浏览器)
await Engine.editor.executerWithOp('OPENFROMSERVER');
// 保存到服务端
await Engine.editor.executerWithOp('SAVESERVER');
// 从本地缓存打开
await Engine.editor.executerWithOp('OPENFROMLOCAL');
// 保存到本地缓存
await Engine.editor.executerWithOp('SAVELOCAL');
// 导入 DWG(弹出文件选择器)
await Engine.editor.executerWithOp('IMPORTDWG');
// 导出为 DWG
await Engine.editor.executerWithOp('EXPORTDWG');
// 导出为 PNG 图片(弹出对话框选择实体、主题色、宽度)
await Engine.editor.executerWithOp('EXPORTPNG');
// 通过 API 直接导出指定实体为 PNG
const { exportEntitiesToImageAndDownload } = vjcad;
await exportEntitiesToImageAndDownload({
entities: selectedEntities,
width: 1920,
theme: 'dark',
fileName: 'drawing.png'
});
// 快速保存(下载 .webcad 文件)
await Engine.editor.executerWithOp('QSAVE');
// 另存为(可指定文件名)
await Engine.editor.executerWithOp('SAVEAS');服务端文件操作 API
DrawingManagerService
const { DrawingManagerService, Engine } = vjcad;
const drawingManager = new DrawingManagerService();从服务端打开图纸
// 打开指定图纸
const openResult = await drawingManager.openDrawing({
type: 'imports', // 类型:'imports' | 'designs'
mapid: 'drawing-123', // 图纸ID
version: 'v1', // 版本号
branch: 'main', // 分支名称
patchId: 'base', // Patch ID(可选,不传则使用最新)
readOnly: false // 是否只读模式
});
if (!openResult.success) {
console.error(`打开失败: ${openResult.error}`);
return;
}
// 加载到编辑器
const webcadData = openResult.webcadData;
const jsonString = openResult.webcadJson;
const docName = `drawing-123_v1_main`;
const virtualFile = new File([jsonString], docName, { type: 'application/json' });
await Engine.view.openDbDoc(virtualFile, webcadData);
// 保存来源信息(用于后续保存)
Engine.currentDoc.serverSource = {
type: 'imports',
mapid: 'drawing-123',
version: 'v1',
branchName: 'main',
lastPatchId: openResult.latestPatchId || 'base'
};
// 保存原始数据(用于增量保存时的 diff 计算)
await Engine.currentDoc.setOriginalJson(openResult.webcadJson);保存到服务端
// 获取当前文档数据
const currentDoc = Engine.currentDoc;
const currentJson = JSON.stringify(currentDoc.toDb());
const originalJson = await currentDoc.getOriginalJson();
const serverSource = currentDoc.serverSource;
// 增量保存
const saveResult = await drawingManager.saveDrawing({
type: serverSource.type,
mapid: serverSource.mapid,
version: serverSource.version,
branchName: serverSource.branchName,
originalJson: originalJson, // 原始数据
currentJson: currentJson, // 当前数据
parentId: serverSource.lastPatchId,
drawingName: '我的图纸',
author: '作者名',
remark: '修改说明'
});
if (saveResult.status) {
console.log(`保存成功! Patch ID: ${saveResult.patchId}`);
// 更新状态
await currentDoc.setOriginalJson(currentJson);
currentDoc.serverSource.lastPatchId = saveResult.patchId;
}图纸类型说明
| 类型 | 说明 |
|---|---|
imports | 已导入的 DWG 图纸,支持增量 patch |
designs | 设计图,从零创建的图纸 |
本地缓存操作 API
本地缓存使用 IndexedDB 存储,支持离线编辑。
获取本地存储服务
const { getLocalStorageService, Engine } = vjcad;
const localService = getLocalStorageService();保存到本地缓存
const currentDoc = Engine.currentDoc;
const currentJson = JSON.stringify(currentDoc.toDb());
const saveResult = await localService.saveDrawing({
serverSource: currentDoc.serverSource, // 服务器来源(可选)
webcadJson: currentJson,
serviceUrl: 'https://api.example.com',
drawingName: '我的图纸'
});
if (saveResult.success) {
console.log(`保存成功! ID: ${saveResult.id}`);
}获取本地图纸列表
const drawings = await localService.listDrawings();
drawings.forEach(drawing => {
console.log(`${drawing.id}: ${drawing.drawingName}`);
});从本地缓存加载
const loadResult = await localService.loadDrawingById(drawingId);
if (loadResult.success) {
console.log('加载成功');
// loadResult 包含 webcadJson, serverSource 等信息
}获取缓存统计
const stats = await localService.getStats();
console.log(`共 ${stats.totalCount} 个图纸, ${stats.totalSize} 字节`);删除本地图纸
await localService.deleteDrawing(drawingId);导入 DWG/DXF
完整流程
const { DrawingManagerService, Service, MapOpenWay, openMapDarkStyle, Engine } = vjcad;
// 1. 创建文件输入
const input = document.createElement('input');
input.type = 'file';
input.accept = '.dwg,.dxf';
input.onchange = async (e) => {
const file = e.target.files[0];
if (!file) return;
const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();
// 2. 上传文件到服务器
const uploadResult = await service.uploadMap(file);
if (uploadResult.error) {
console.error('上传失败:', uploadResult.error);
return;
}
// 3. 生成图纸 ID
const mapid = file.name.replace(/\.(dwg|dxf)$/i, '') + '_' + Date.now();
// 4. 解析 DWG 文件
const openResult = await service.openMap({
mapid: mapid,
fileid: uploadResult.fileid,
uploadname: file.name,
mapopenway: MapOpenWay.Memory,
style: openMapDarkStyle()
}, true);
if (openResult.error) {
console.error('解析失败:', openResult.error);
return;
}
// 5. 获取 webcad 数据并加载
const drawingResult = await drawingManager.openDrawing({
type: 'imports',
mapid: openResult.mapid,
version: openResult.version,
branch: 'main'
});
if (drawingResult.success) {
const virtualFile = new File(
[drawingResult.webcadJson],
'drawing.webcad',
{ type: 'application/json' }
);
await Engine.view.openDbDoc(virtualFile, drawingResult.webcadData);
// 6. 保存来源信息
Engine.currentDoc.serverSource = {
type: 'imports',
mapid: openResult.mapid,
version: openResult.version,
branchName: 'main',
lastPatchId: drawingResult.latestPatchId || 'base'
};
await Engine.currentDoc.setOriginalJson(drawingResult.webcadJson);
}
};
// 触发文件选择
input.click();支持的格式
| 格式 | 说明 |
|---|---|
.dwg | AutoCAD 原生格式 |
.dxf | 图形交换格式 |
导出 DWG
命令方式
await Engine.editor.executerWithOp('EXPORTDWG');API 方式
const { DrawingManagerService, Engine } = vjcad;
const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();
// 获取当前文档数据
const currentDoc = Engine.currentDoc;
const webcadJson = JSON.stringify(currentDoc.toDb());
// 调用导出接口
const exportResult = await service.exportDwg({
webcadJson: webcadJson,
filename: 'exported.dwg',
version: 'AC1027' // DWG 版本:AC1027 = AutoCAD 2013
});
if (exportResult.success) {
// 下载文件
const blob = new Blob([exportResult.data], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'exported.dwg';
a.click();
URL.revokeObjectURL(url);
}新建文档
// 新建空白文档
Engine.view.newDocument();
// 设置文档名称
Engine.currentDoc.name = '新图纸';关键属性
Engine.currentDoc.serverSource
保存图纸的服务器来源信息,用于后续保存和同步。
Engine.currentDoc.serverSource = {
type: 'imports', // 图纸类型
mapid: 'drawing-123', // 图纸 ID
version: 'v1', // 版本号
branchName: 'main', // 分支名称
lastPatchId: 'patch-456' // 最后的 Patch ID
};Engine.currentDoc.isReadOnly
设置文档为只读模式。
Engine.currentDoc.isReadOnly = true;增量保存说明
WebCAD 使用增量保存机制:
- 原始数据:通过
setOriginalJson()保存的基准数据 - 当前数据:通过
toDb()获取的当前文档数据 - Diff 计算:服务端比较两者差异,只保存变更部分
- Patch 链:每次保存生成一个 Patch,形成版本历史
好处:
- 节省存储空间
- 支持版本回溯
- 支持多人协作冲突检测
模板成图
从 imports 模板新建图纸、克隆实体并导出 DWG(保留模板字体/线型/填充),见 模板成图。