File Operations
File Operations
WebCAD provides complete drawing file management capabilities, including server-side storage, local cache, DWG import/export, and more.
Overview
File operations are divided into the following categories:
| Category | Command | Description |
|---|---|---|
| Server operations | OPENFROMSERVER / SAVESERVER | Open/save drawing from/to server |
| Local cache | OPENFROMLOCAL / SAVELOCAL | Open/save drawing from/to IndexedDB |
| Local file | QSAVE / SAVEAS | Download .webcad file |
| DWG conversion | IMPORTDWG / EXPORTDWG | Import/export DWG format |
| Image export | EXPORTPNG | Export current view as PNG image |
Core Services
DrawingManagerService
DrawingManagerService is the core service for drawing management, encapsulating all server-side operations.
import { DrawingManagerService } from 'vjcad';
const drawingManager = new DrawingManagerService();LocalStorageService
LocalStorageService manages local IndexedDB storage and supports offline editing.
import { getLocalStorageService } from 'vjcad';
const localService = getLocalStorageService();Open Drawing from Server
Command Method
// Execute OPENFROMSERVER command, opens drawing browser dialog
await Engine.editor.executerWithOp('OPENFROMSERVER');API Method
import { DrawingManagerService, Engine } from 'vjcad';
const drawingManager = new DrawingManagerService();
// Open drawing
const openResult = await drawingManager.openDrawing({
type: 'imports', // Type: 'imports' | 'designs'
mapid: 'example_map', // Drawing ID
version: 'v1', // Version number
branch: 'main', // Branch name
patchId: 'base', // Patch ID (optional, omit to use latest)
readOnly: false // Read-only mode
});
if (openResult.success) {
// Load into editor
const virtualFile = new File(
[openResult.webcadJson],
'drawing.webcad',
{ type: 'application/json' }
);
await Engine.view.openDbDoc(virtualFile, openResult.webcadData);
// Save source info (for subsequent save)
Engine.currentDoc.serverSource = {
type: 'imports',
mapid: 'example_map',
version: 'v1',
branchName: 'main',
lastPatchId: openResult.latestPatchId || 'base'
};
// Save original data (for diff calculation during incremental save)
await Engine.currentDoc.setOriginalJson(openResult.webcadJson);
}Open Parameters IOpenDrawingParams
| Parameter | Type | Required | Description |
|---|---|---|---|
type | 'imports' | 'designs' | Yes | Drawing type |
mapid | string | Required for imports | Drawing ID |
version | string | Required for imports | Version number |
designPath | string | Required for designs | Design drawing path |
branch | string | No | Branch name, default "main" |
patchId | string | No | Specific patch version, empty to get latest |
readOnly | boolean | No | Read-only mode |
clipbounds | [number, number, number, number] | No | Clip bounds, only returns entities within range |
editAreas | Array<{minX, minY, maxX, maxY}> | No | Multiple edit areas (tile mode) |
editLayers | string[] | No | Edit layer names |
Open Result IOpenDrawingResult
| Property | Type | Description |
|---|---|---|
success | boolean | Whether successful |
error | string | Error message |
webcadJson | string | Decompressed webcad JSON data |
webcadData | any | Parsed object |
latestPatchId | string | Latest Patch ID |
isReadOnly | boolean | Read-only mode |
Save to Server
Command Method
await Engine.editor.executerWithOp('SAVESERVER');API Method
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, // Original data (for diff calculation)
currentJson: currentJson, // Current data
parentId: serverSource.lastPatchId,
drawingName: 'My Drawing',
author: 'Author',
remark: 'Modification notes'
});
if (saveResult.status) {
// Update original data and patchId
await currentDoc.setOriginalJson(currentJson);
currentDoc.serverSource.lastPatchId = saveResult.patchId;
}Save Parameters ISaveDrawingParams
| Parameter | Type | Required | Description |
|---|---|---|---|
type | 'imports' | 'designs' | Yes | Drawing type |
mapid | string | Required for imports | Drawing ID |
version | string | Required for imports | Version number |
designPath | string | Optional for designs | Design drawing path, empty for new |
branchName | string | No | Branch name, default "main" |
originalJson | string | No | Original webcad JSON (for diff calculation) |
currentJson | string | Yes | Current webcad JSON |
parentId | string | No | Parent Patch ID (for conflict detection) |
drawingName | string | No | Drawing name |
author | string | No | Author |
remark | string | No | Remark |
Incremental Save Features
- Save only modified parts: Calculates diff, saves storage space and network bandwidth
- Version history support: Each save generates a new patch
- Multi-user collaboration conflict detection: Detects concurrent modifications via parentId
Local Cache Operations
Local cache uses IndexedDB storage and supports offline editing.
Save to Local
import { getLocalStorageService, Engine } from 'vjcad';
const localService = getLocalStorageService();
const currentDoc = Engine.currentDoc;
const currentJson = JSON.stringify(currentDoc.toDb());
const result = await localService.saveDrawing({
serverSource: currentDoc.serverSource,
webcadJson: currentJson,
serviceUrl: 'https://api.example.com',
drawingName: 'My Drawing'
});
if (result.success) {
console.log(`Save successful! ID: ${result.id}`);
}Open from Local
// Get all local drawing list
const drawings = await localService.listDrawings();
// Load drawing by ID
const loadResult = await localService.loadDrawingById(drawingId);
if (loadResult.success) {
const virtualFile = new File(
[loadResult.webcadJson],
'local.webcad',
{ type: 'application/json' }
);
await Engine.view.openDbDoc(virtualFile);
// Restore server source info
Engine.currentDoc.serverSource = {
type: loadResult.record.type,
mapid: loadResult.record.mapid,
version: loadResult.record.version,
branchName: loadResult.record.branchName,
lastPatchId: loadResult.record.lastPatchId
};
}LocalStorageService API
| Method | Description |
|---|---|
saveDrawing(params) | Save drawing to local |
loadDrawing(key) | Load drawing by key |
loadDrawingById(id) | Load drawing by ID |
listDrawings(type?) | List all local drawings |
deleteDrawing(key) | Delete drawing |
deleteDrawingById(id) | Delete drawing by ID |
clearAll() | Clear all local cache |
getStats() | Get cache statistics |
exists(key) | Check if drawing exists |
Local Cache Features
- IndexedDB storage: Large capacity, supports storing large drawings
- Offline access: Editable without network
- Saves server source info: Supports subsequent sync to server
- Auto-compression: Uses vcad format compression to save space
Download .webcad File
QSAVE - Quick Save
Download directly using current filename.
// Command method
await Engine.editor.executerWithOp('QSAVE');
// API method
const currentDoc = Engine.currentDoc;
const data = currentDoc.toDb();
const jsonString = JSON.stringify(data, null, 2);
const blob = new Blob([jsonString], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = (currentDoc.name || 'untitled') + '.webcad';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);SAVEAS - Save As
Opens dialog to customize filename.
await Engine.editor.executerWithOp('SAVEAS');.webcad File Format
- JSON format: Easy to parse and debug
- Contains complete drawing data: Entities, layers, styles, etc.
- Openable via OPEN command: Or drag and drop into editor
Import DWG
Command Method
await Engine.editor.executerWithOp('IMPORTDWG');API Method
import { DrawingManagerService, Service, MapOpenWay, openMapDarkStyle } from 'vjcad';
const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();
// 1. Upload file
const uploadResult = await service.uploadMap(file);
if (uploadResult.error) {
throw new Error('Upload failed: ' + uploadResult.error);
}
// 2. Parse DWG
const mapid = file.name.replace(/\.(dwg|dxf)$/i, '') + '_' + Date.now();
const openResult = await service.openMap({
mapid: mapid,
fileid: uploadResult.fileid,
uploadname: file.name,
mapopenway: MapOpenWay.Memory,
style: openMapDarkStyle()
}, true);
if (openResult.error) {
throw new Error('Parse failed: ' + openResult.error);
}
// 3. Get webcad data and load
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);
Engine.currentDoc.serverSource = {
type: 'imports',
mapid: openResult.mapid,
version: openResult.version,
branchName: 'main',
lastPatchId: drawingResult.latestPatchId || 'base'
};
await Engine.currentDoc.setOriginalJson(drawingResult.webcadJson);
}Supported File Formats
- DWG: AutoCAD drawing format (versions 2000-2018)
- DXF: Drawing Exchange Format
Export DWG
Command Method
await Engine.editor.executerWithOp('EXPORTDWG');API Method
const currentDoc = Engine.currentDoc;
const currentJson = JSON.stringify(currentDoc.toDb());
const serverSource = currentDoc.serverSource;
const result = await drawingManager.exportToDwg({
type: serverSource.type,
webcadJson: currentJson,
mapid: serverSource.mapid,
version: serverSource.version,
branch: serverSource.branchName,
cadVersion: '', // CAD version, empty for auto
isZoomExtents: false, // Zoom to extents
useCache: true, // Use cache
unGroup: false, // Ungroup
exportDimAsNative: false // Export as native dimension
});
if (result.status && result.downloadUrl) {
window.open(result.downloadUrl, '_blank');
}Export Parameters IExportToDwgParams
| Parameter | Type | Description |
|---|---|---|
type | 'imports' | 'designs' | Drawing type |
webcadJson | string | Current webcad JSON data |
mapid | string | Drawing ID (imports type) |
version | string | Version number (imports type) |
designPath | string | Design drawing path (designs type) |
branch | string | Branch name |
cadVersion | string | CAD version (2000-2018) |
isZoomExtents | boolean | Zoom to extents on export |
useCache | boolean | Use cache |
unGroup | boolean | Ungroup |
exportDimAsNative | boolean | Export dimensions as native CAD dimensions |
Export Notes
- imports type: Incremental export based on original DWG, preserves original format
- designs type: Fresh export, does not depend on original file
- Native dimensions: Option to convert WebCAD dimensions to AutoCAD native dimensions
Export PNG Image
Renders the current drawing as PNG/JPEG image and downloads directly. Reuses entities already in memory for offscreen rendering (supports all entity types: block references, text, hatches, dimensions, etc.), no server involvement required.
Command Method
// Opens export dialog (select entities, theme color, dimensions, etc.)
await Engine.editor.executerWithOp('EXPORTPNG');API Method
import { exportEntitiesToImageAndDownload, exportEntitiesToImage } from 'vjcad';
// Export all entities (transparent background PNG by default)
await exportEntitiesToImageAndDownload({
width: 2048,
fileName: 'my-drawing.png'
});
// Export with white background (disable transparency)
await exportEntitiesToImageAndDownload({
width: 2048,
transparent: false,
theme: 'light',
fileName: 'my-drawing-white.png'
});
// Export specified entities (transparent background)
await exportEntitiesToImageAndDownload({
entities: [line1, circle1],
width: 1280,
fileName: 'partial-export.png'
});
// Export as JPEG (JPEG does not support transparency, uses theme color background automatically)
await exportEntitiesToImageAndDownload({
width: 1920,
theme: 'dark',
mimeType: 'image/jpeg',
quality: 0.9,
fileName: 'my-drawing.jpg'
});
// Get Blob for custom processing (e.g. upload to server)
const result = await exportEntitiesToImage({
entities: myEntities,
width: 1920
});
if (result.success && result.blob) {
const formData = new FormData();
formData.append('file', result.blob, 'screenshot.png');
// await fetch('/upload', { method: 'POST', body: formData });
}Export Parameters IExportImageOptions
| Parameter | Type | Default | Description |
|---|---|---|---|
entities | EntityBase[] | All entities in current space | Entity array to export |
width | number | 1000 | Image width (pixels), render canvas max 4096px |
height | number | Auto-calculated | Image height (auto-calculated from entity bounds aspect ratio when omitted) |
theme | 'dark' | 'light' | 'light' | Theme color, only affects colorIndex 7 inversion when transparent |
transparent | boolean | true | Transparent background (PNG only, JPEG ignores) |
mimeType | 'image/png' | 'image/jpeg' | 'image/png' | Image format |
quality | number | 0.92 | JPEG quality (0-1), JPEG only |
fileName | string | 'export.png' | Download filename |
Notes
- Exports transparent background PNG by default, suitable for documents, PPT, etc.
- Set
transparent: falsefor opaque background, background color controlled bytheme lighttheme: White background, colorIndex 7 (white) auto-inverted to blackdarktheme: Black background, colorIndex 7 stays white- When transparent,
themeonly affects colorIndex 7: black forlight, white fordark - JPEG does not support transparency channel,
transparentis ignored - Height auto-calculated from entity bounding box aspect ratio
- Render canvas max 4096px, auto-scaled when exceeded for output size
- Pure frontend implementation, direct download, no server involvement
Auto-Open Drawing via URL Parameters
WebCAD supports controlling page behavior after load via URL parameters, including auto-opening a specified drawing and activating sidebar panels.
Supported URL Parameters
All URL parameters use the vcad_ prefix:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
vcad_mapid | string | Yes | - | Drawing ID |
vcad_version | string | No | Latest version | Version number |
vcad_branch | string | No | main | Branch name |
vcad_patch | string | No | base | Patch ID |
vcad_readonly | boolean | No | false | Open in read-only mode |
vcad_tile | boolean | No | false | Open in tile mode |
vcad_panel | string | No | - | Sidebar panel name to activate after init |
Usage Examples
// Auto-open specified drawing
https://your-domain.com/?vcad_mapid=building_plan
// Open specified version, read-only mode
https://your-domain.com/?vcad_mapid=building_plan&vcad_version=v2&vcad_readonly=true
// Open large drawing in tile mode
https://your-domain.com/?vcad_mapid=city_map&vcad_tile=true
// Open drawing and activate AI assistant panel
https://your-domain.com/?vcad_mapid=building_plan&vcad_panel=ai-assistant
// Activate sidebar panel only (no drawing open)
https://your-domain.com/?vcad_panel=ai-assistantProcessing Flow
- After page load, parse
vcad_parameters from URL - If
vcad_panelexists, activate the specified sidebar panel - If
vcad_mapidexists, open drawing with the following flow:- Check if server has converted drawing (imports list)
- If yes, open directly
- If no, check if original drawing exists in background (serverMaps)
- If original exists, import and open (backend auto-converts)
- If
vcad_tile=true, open in tile mode
Access URL Parameter Constants in Code
import { MainView } from 'vjcad';
// All URL parameter names defined in MainView.URL_PARAMS
console.log(MainView.URL_PARAMS.MAPID); // 'vcad_mapid'
console.log(MainView.URL_PARAMS.VERSION); // 'vcad_version'
console.log(MainView.URL_PARAMS.BRANCH); // 'vcad_branch'
console.log(MainView.URL_PARAMS.PATCH); // 'vcad_patch'
console.log(MainView.URL_PARAMS.READONLY); // 'vcad_readonly'
console.log(MainView.URL_PARAMS.TILE); // 'vcad_tile'
console.log(MainView.URL_PARAMS.PANEL); // 'vcad_panel'Drawing List Query
Get All Drawing List
const allDrawings = await drawingManager.listAllDrawings();
// Background DWG drawings
console.log('Background drawings:', allDrawings.serverMaps);
// Imported drawings (imports)
console.log('Imported drawings:', allDrawings.imports);
// User design drawings (designs)
console.log('Design drawings:', allDrawings.designs);Get WebCAD Drawing List
const webcadDraws = await drawingManager.listWebcadDraws({
mapid: 'example_map', // Optional, filter by mapid
version: 'v1' // Optional, filter by version
});Branch Management
For detailed branch management operations, see Versioning.
// Create branch
await drawingManager.createBranch({
type: 'imports',
mapid: 'example_map',
version: 'v1',
sourceBranch: 'main',
newBranch: 'feature-1',
author: 'Author'
});
// Get branch list
const branches = await drawingManager.listBranches({
type: 'imports',
mapid: 'example_map',
version: 'v1'
});
// Merge branch
await drawingManager.mergeBranch({
type: 'imports',
mapid: 'example_map',
version: 'v1',
sourceBranch: 'feature-1',
targetBranch: 'main'
});Keyboard Shortcuts
| Shortcut | Function |
|---|---|
Ctrl + O | Open file |
Ctrl + S | Quick save |
Ctrl + Shift + S | Save as |
Next Steps
- Versioning - Learn about branch and version management
- Tile Mode - Large drawing partitioned editing
- System Commands - View all system commands