分享

关于批量打印CAD的几点体会(VB.NET+COM=PDF)|编程与CAD二次开发

 bubbi7 2015-10-10
两年没写体会了,这中间发生了很多有意义的事。包括顺利完成Master Degree。走上攻城师的不归路。开始意识到压力之大,工资和房价的悬殊。唯有保持看书、思考,才能不让自己对现实的苦逼屈服,多学点东西,相信岩土工程还是很有钱途。


闲话少说,今天想谈谈工作中常需要做的一个事:出版。


无论是打印成pdf,还是发送到打印机,道理是类似的。
批量打印WORD,EXCEL,CAD的意义就不说了,大项目动辄几百张DWG汇总。


目前打印CAD有很多工具,很多人只是知道,但对于其原理还是不太清楚,一旦遇到故障了,也不知道如何解决。下面先讲讲批量打印的原理,贴一些代码,懂编程的同行可以拿回去稍加修改,做成自己想要的样子。


CAD有两个主要的表达空间,模型和布局,我们经常会在这两个空间类型里面打印图纸。
‘=================================================================
模型modelspace的打印
通常是图框为一个外部参照(或某个特定图层上的多段线),批量打印的流程是:
打开dwg->配置打印参数->遍历modelspace里面的实体->找出参照对象->判断是否为图框对象->获取对象的范围(GetBoundingBox函数)->将范围赋值给打印设置->窗口方式打印->出图完成。
下面是这个流程的主要代码,逐句看看相信很快就能知道是怎么回事儿
’==============================================================
   Dim ptMin As Variant, ptMaxAs Variant
    Dim Ent As AcadEntity
    Dim PlotCount As Integer
    
    Set objDoc = ThisDrawing.Application.ActiveDocument
    Set objLayout = objDoc.Layouts.Item("Model")
    Set objPlot = objDoc.Plot
     ThisDrawing.Application.ZoomExtents
    
        '
设置打印机
        If Not Trim(PrinterName) ="" Then
         objLayout.ConfigName ="pdfFactory Pro"

        Else
        Exit Sub
        End If
        
        ' 设置打印样式表
           objLayout.StyleSheet = "acad.ctb"

  
         objLayout.CanonicalMediaName = "A3"
        
        '
设置图纸单位
         objLayout.PaperUnits = acMillimeters
      
        '
设置默认图纸打印方向
         objLayout.PlotRotation= ac0degrees     '
横向

        '
设置图纸打印比例
         objLayout.StandardScale = ac1_1
         objLayout.UseStandardScale = True  '
使用标准打印比例


        '
设置图纸是否居中打印
         objLayout.CenterPlot = True
        
        '
打印时使用图形文件中的线宽
         objLayout.PlotWithLineweights = True

        '
设置是否应用打印样式
         objLayout.PlotWithPlotStyles = True

        ' 将打印错误报告切换为静默错误模式,以便不间断地执行打印任务
         objPlot.QuietErrorMode = True

        '
重新生成当前图形
         objDoc.Regen acAllViewports
        
        '
设置前台打印,使打印任务按打印顺序依次发送到打印机
         objDoc.SetVariable "BACKGROUNDPLOT",0
      '
至此配置打印机完成。准备查找图框
        For Each Ent In objDoc.ModelSpace
        If TypeOf Ent IsAcadBlockReference Then ‘如果对象是参照的话,进入下面判断
            IfIsFrame(Ent, AutoFrame) = True And objDoc.Blocks(Ent.Name).count > 0 Then
                 Ent.GetBoundingBox ptMin, ptMax
                 Debug.Print Ent.Name & "--"& objDoc.Blocks(Ent.Name).count
                
                '
将三维点转化为二维点坐标
                ReDim Preserve ptMin(0 To1)
                ReDim Preserve ptMax(0 To1)
            
                '
设置打印窗口
                 ThisDrawing.ActiveLayout.SetWindowToPlotptMin, ptMax
                 objLayout.PlotType = acWindow
                  End If

                 objPlot.PlotToDevice objLayout.ConfigName '这句话就是发送到打印机了、

        End If
        Next Ent



‘其中IsFrame函数为
Public FunctionIsFrame(entobj As Object, AutoMode As Boolean) As Boolean  '判断是否为图框
On Error Resume Next
IsFrame = False
Dim i As Integer
Dim FrmNameList As Variant
FrmNameList = "blkFrame,A1,A2,A3,TK,图框"   '
图框块、编组名列表
FrmNameList = Split(FrmNameList, ",")
For i = 0 To UBound(FrmNameList)
If entobj.Name = FrmNameList(i) Then
IsFrame = True
Exit For
End If
Next

End Function
’=========================================================
当图框不是参照,是位于某个图层上的多段线时,我们可以通过构建选择集,将那个图层上的多段线加入,然后遍历选择集(同橙色部分)dim ent as acadpolyline或acadlightpolyline,然后还是getboundingbox获取打印范围。


布局layout的打印
其批量打印的原理可以不同,这取决于制图习惯。对于自动成图的比如桥和路线,通常是一个布局一张图,一个cad几十个布局序列。还有一种是一个布局里面很多张图,每个图有一个图框参照。
对于前一种情况,方法为
遍历dwg的layouts集合,对一个集合layout(i)进行如上的配置,注意 objLayout.CenterPlot = false,布局不能居中打印。
dim i as acadlayout
for each i in acadoc.layouts
'将上面的代码中 objLayout换成i,配置打印机,打印方式PlotType = acLayout,此处省略重复。
i.PlotToDevice i.ConfigName
next
如此,即可把所有布局打印。
对于一个布局里面很多个图纸的,同上,例如layout(i)里面很多,那就遍历layout(i)里面的外部参照,将每个参照的GetBoundingBox获取下来,采用plotType=acWindow的方式,同modelspace一样的方法打印


如果仔细看到这里,有一定的VBA基础的同行们,估计已经知道CAD内部的打印原理了,过去一直没静下研究下这个,最近花了点时间看明白后,就自己写了一个,然后集成了自动打印word和excel。现在遇到不工作,或者打印图纸方向不对,纸张不对的,就可以随时对源代码修改。
关于打印WORD和excel,大家可以用录制宏的办法,查看自动生成的代码,然后修改移植,就可以放到VB6.0或者VB.NET里面了。
用VB.net或6.0采用com组件独立编制exe程序时,区别是程序启动时定义AcadApp=GetObject(,"AutoCAD.Application) 或new一个Application。Thisdrawing替换为AcadDoc=AcadApp.ActiveDocument.
今天先到这,敲累了休息下,U盘没带回来。
另外国庆七天假,祝各位同行朋友玩的愉快。
最后插一句广告,承接边坡支护设计(计算书,施工图,数量表),搞地基处理设计图,搞小型基坑支护。也搞CAD,excel二次开发,挣点零花钱。筒子们项目上有闲钱的恰好需要上述服务的,支援下,房租要涨价咯。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约