Skip to content
On this page

打开和保存图纸

mxweb文件

mxweb文件是 mxcad 支持打开的特定文件类型,传统的CAD图纸文件格式可通过云图开发包转换为mxweb文件,具体操作可参考图纸转换

打开mxweb文件

mxcad实例对象首先传入的参数是mxweb文件的网络路径,即通过互联网可以直接访问到对应的mxweb文件。如果我们想在本地直接打开mxweb文件,可调用方法openWebFile() 直接打开本地mxweb文件

ts
import {  MxCpp } from "mxcad"

const input = document.createElement("input")
input.type = "file"
input.addEventListener("change", (e:any)=> {
    const filePath = URL.createObjectURL(e.target.files[0])
    MxCpp.getCurrentMxCAD().openWenFile(filePath)
})
document.body.appendChild(input)

保存mxweb文件

mxcad 中提供了实例方法 saveFile() 来保存编辑后的mxweb文件。其中,该方法提供了多个parameter参数,用户可根据自身需求设置对应参数值,具体参数设置可参考saveFile() API文档。例如保存的mxweb文件不进行压缩(打开速度更快,文件体积变大),可将 saveFile() 最后一个参数设置为{ compression: 0 }

ts
import {  MxCpp } from "mxcad"

const btn = document.createElement("button")
btn.addEventListener("click",()=>{
    MxCpp.getCurrentMxCAD().saveFile(void 0, void 0, true, true, { compression: 0 })
})
document.body.appendChild(btn)

注意

saveFile()方法最好是在用户触发的事件中调用, 这样才有权限调用浏览器提供的保存文件对话框, 否则可能会报错或者直接下载mxweb文件

在某些特殊情况下我们不希望直接下载mxweb文件, 那么可以在回调函数中得到该文件的二进制数据。

ts
import {  MxCpp } from "mxcad"

MxCpp.getCurrentMxCAD().saveFile(void 0, (data)=> {
      let blob: Blob
      let isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
      if (isSafari) {
        blob = new Blob([data.buffer], { type: "application/octet-stream" });
      } else {
        blob = new Blob([data.buffer], { type: "application/octet-binary" });
      }
}, false, true, { compression: 0 })

清空当前打开文件

mxcad 中提供了实例方法 newFile() 来清空所有内容。

ts
import { MxCpp, McObject } from "mxcad" ;

let mxcad:McObject = MxCpp.getCurrentMxCAD();
mxcad.newFile();

图纸打开完成事件

mxcad 打开图纸完成后,会触发 onOpenFileComplete 事件,用户可以在该事件里面做一些加载图纸后的一些工作。

ts
import { createMxCad } from "mxcad";
createMxCad({
    canvas: "#mxcad",
    locateFile: (fileName) => new URL(`/node_modules/mxcad/dist/wasm/2d/${fileName}`, import.meta.url).href,
    // 提供要打开的文件 注意../assets/test.mxweb 是相对路径下的文件地址, 
    // 在vite中可用通过这样的方式得到该文件正确的的网络地址
    fileUrl: new URL("../assets/test.mxweb", import.meta.url).href,
    // 提供加载字体的目录路径
    fontspath: new URL("node_modules/mxcad/dist/fonts", import.meta.url).href, 
    onOpenFileComplete:()=>{
      console.log("成功打开文件!")
    }
})

保存为JPG

我们调用 mxdraw 提供的 createCanvasImageData() 方法,把当前图纸保存为jpg文件,其实质为将当前显示内容,变成image数据输出。具体详情请参考API文档 createCanvasImageData()

示例demo参考:导出jpg功能

ts
import { MxFun } from "mxdraw";

MxFun.getCurrentDraw().createCanvasImageData(
    (imageData: String) => {
        const newWindow: any = window.open();
        if (newWindow != null) {
            newWindow.document.write('<img src="' + imageData + '"/>');
            setTimeout(() => {
                newWindow.print();
            }, 300);
        }
    },
    {
        width: 349,// 图片宽
        height: 536,// 图片高
        // range_pt1: ret.pt1.toVector3(), // 截图范围角点1
        // range_pt2: ret.pt2.toVector3(), // 截图范围角点2
    }
);

保存为PDF

我们可以通过 mxcad 实例对象提供的 saveFileToUrl() 方法把mxweb文件先保存到服务器上,再将目标文件转成pdf。

点击 McObject.saveFileToUrl() 查看方法详情。

示例demo参考:导出pdf功能

ts
import { MxCpp, McObject, MxTools } from "mxcad"

MxCpp.getCurrentMxCAD().saveFileToUrl("http://localhost:1337/mxcad/print_to_pdf", (iResult, sserverResult) => {
    try {
      let ret = JSON.parse(sserverResult);
      if (ret.ret == "ok") {
        // filePath:文件地址
        // 利用mxcad提供的帮助工具根据fileParh文件地址下载目标文件
        MxTools.downloadFileFromUrl(filePath, ret.file);
      }
      else {
        console.log(sserverResult);
      }
    } catch {
      console.log("Mx: sserverResult error");
    }
  }, undefined, param);// param:文件保存参数

注意

http://localhost:3337/mxcad/print_to_pdf 该示例接口实际就是云图开发包中提供的图纸转pdf对应的Node服务

CAD图纸

在现实 mxcad项目 开发过程中,我们会遇到在项目中直接打开CAD图纸的需求,但由于 mxcad 只能打开mxweb文件,因此其本质上还是需要将CAD图纸转换为mxweb文件。该需求最基础的实现方法为:上传CAD图纸到我们提供的Node服务,并得到该服务返回的转换后的mxweb文件的前端对应访问地址。默认情况下我们可以直接在开发包下找到对应的Node服务源码, 直接使用对应接口, 但是可能它并不能完全满足你的需求,需要自己修改甚至重写。因此,我们可根据下列方法实现图纸转换的接口。

打开CAD图纸示例项目地址: https://demo.mxdraw3d.com:3000/mxcad/

示例项目对应的Node服务, 请点击查看该链接了解详情:https://help.mxdraw.com/?pid=115

后端具体实现

首先我们需要安装Node环境,再通过Node child_process 使用子进程调用云图开发包中的mxcadassembly程序。并通过改变参数srcpathoutname 将mxweb文件保存为dwg图纸。最后我们可以将转换的文件放在服务器上,也可以上传到oss或者其他云存储上,返回对应的访问地址。

将CAD图纸上传到服务器上, 请具体参考https://help.mxdraw.com/?pid=115

结合云图开发包MxDrawCloudServer\Bin\MxCAD\MxCADSaveFile\server.js文件查看到源码可以非常清晰的知道如何上传CAD实现转换和保存dwg图纸。

ts
const { exec } = require('child_process');
// 如果是要将mxweb格式文件转成服务器 那么 srcpath就是mxweb文件路径 而outname 的后缀名应该是对应图纸的后缀名,如: test.dwg
const param = {
  srcpath: "要转换的文件在服务器上的路径",
  outpath: "转换后生成的文件在服务器上的目录路径",
  outname: "转换后的文件名称"
}
exec(`"mxcadassembly程序在服务器所在位置" "${JSON.stringify(param)}"`)

注意

mxcadassembly程序所在目录:

windows目录: MxDrawCloudServer\Bin\MxCAD\Release\mxcadassembly.exe

linux目录: MxDrawCloudServer\Bin\Linux\BinMxCAD\mxcadassembly

前端具体实现(保存DWG图纸到服务器)

将目前网页上打开的mxweb文件保存成CAD图纸,首先我们需要得到现在修改后的mxweb文件数据,然后上传到服务器,后端将mxweb格式的数据写在一个mxweb格式的文件中,最后使用mxcadassembly程序将mxweb格式文件转换为CAD图纸的文件, 然后返回对应的访问地址。

默认情况下, 我们提供saveFileToUrl 来实现保存CAD图纸, 它实际上帮我们将当前的mxweb数据上传到了你指定的一个后端接口中,从而实现了文件保存到服务器的效果。由于 mxcad 打开的文件是 .mxweb 格式,因此你初始保存的文件也都是 .mxweb 格式的,因此如果你想要保存为 .dwg 格式的图纸文件,则需要在后端进行格式转换。其中,我们的云图开发包中提供了保存.mxweb 格式和 .dwg 格式的文件到服务器的后端接口,该接口也可根据自己项目的具体需求去自己实现。

点击 McObject.saveFileToUrl() 查看方法详情。

下面是它的使用方法:

ts
import { MxCpp, MxTools } from "mxcad"

/**
 * 保存文件的后端接口:"http://localhost:3337/mxcad/savefiledwg"
 */

MxCpp.getCurrentMxCAD().saveFileToUrl("http://localhost:3337/mxcad/savefiledwg", (iResult, sserverResult)=> {
  /** 这个就是对应接口的返回数据结果 */ 
  console.log(sserverResult)

  // 我们可以直接拿到请求结果中携带的CAD图纸的访问地址 下载对应的图纸
  // 假设返回结果是filePath
  const filePath = JSON.parse(sserverResult).filePath

   fetch(filePath).then(async (res)=> {
    const blob = await res.blob()
    // 默认使用了一些新的特性,如果不支持则会自动降级使用a标签下载
    MxTools.saveAsFileDialog({
      blob,
      filename: "test.dwg",
      types: [{
        description: "dwg图纸",
        accept: {
            "application/octet-stream": [".dwg"],
        },
      }]
    })
  })
})

注意

http://localhost:3337/mxcad/savefiledwg 该示例接口实际就是云图开发包中提供的对应的Node服务

  • '/mxcad/savefiledwg':保存dwg文件到服务器
  • '/mxcad/savefile':保存mxweb文件到服务器

在实际使用时,这种常规的方法可能并不能满足用户的需求, 这个时候我们可以自己来实现这个保存dwg的功能,请参考如下代码:

ts
import { MxCpp } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()
// 这里直接拿到mxweb数据
mxcad.saveFile(void 0, (data)=> {
      let blob: Blob
      const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
      if (isSafari) {
        blob = new Blob([data.buffer], { type: "application/octet-stream" });
      } else {
        blob = new Blob([data.buffer], { type: "application/octet-binary" });
      }
      // 这里直接将blob转成file
      const file = new File([blob], 'test.mxweb', { type: isSafari ? "application/octet-stream" : "application/octet-binary" })
      // 上传文件转CAD图纸
      fetch('http://localhost:3337/mxcad/savefiledwg', {
          method:'POST',
          body: file
      })
}, false, true)

CAD图纸转换DEMO源码

如果你希望快速的理解云图开发包前后端源代码是如何实现打开和保存CAD图纸的, 请结合上述内容下载一个最简单打开保存CAD图纸的DEMO源码, 方便快速理解源码。

该DEMO 是一个Node服务, 需要安装Node环境

查看是否安装完成

sh
node -v
npm -v

点击下载源码

下载好demo后 解压进入目录

sh
node app.js

最后控制台会提示访问: http://localhost:3333

现在就可以进入页面查看效果了。

本DEMO中 mxcad和mxdraw是通过CDN方式引入的, 如果你发现打开页面后没有CAD图纸显示,可能是你无法访问CDN资源 你可以选择通过npm安装下载mxcad和mxdraw库来替换CDN上的资源

sh
npm init
npm install mxcad mxdraw

安装好后,在目录会出现node_modules文件夹

然后将CDN引入改成node_modules包中对应的mxcad和mxdraw目录下的相关资源本地引入就好

这里给出需要改动的地方 就是将https://unpkg.com 替换成./node_modules

index.html:

ts
// 改动前
<script src="https://unpkg.com/mxdraw" crossorigin="anonymous"></script>
<script src="https://unpkg.com/mxcad" crossorigin="anonymous"></script>
createMxCad({
    locateFile: (fileName) => {
        return self.location.origin + "/mxcad_docs/wasm/2d-st/" + fileName
    },
    fontspath: "https://unpkg.com/mxcad/dist/fonts",
})

// 改动后
<script src="./node_modules/mxdraw/dist/mxdraw.umd.js" crossorigin="anonymous"></script>
<script src="./node_modules/mxcad/dist/mxcad.umd.js" crossorigin="anonymous"></script>
createMxCad({
    locateFile: (fileName) => {
        return "./node_modules/mxcad/dist/wasm/2d-st/" + fileName
    },
    fontspath: "./node_modules/mxcad/dist/fonts",
})

注意

1.源码提供的图纸转换程序不是最新的, 正式开发请使用云图开发包

2.源码只是用于学习理解打开保存CAD图纸的过程, 理解后请自行实现后台服务

3.学习后再去看云图开发包中的Node服务源码会更加容易理解