- 积分
- 120
- 明经币
- 个
- 注册时间
- 2010-6-2
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 作者 于 2010-6-3 10:42:04 编辑
看了kean的打印专栏后。自己想做个多文档打印功能的程序。
首先介绍下我自己想处理的图纸是那种一个文件中有好几张图形的文件。我的程序希望能够自动搜索到每个图形的窗体范围然后按照一定的顺序依次将每个图形打印出来。这个功能已经可以实现了。
现在的问题是希望能够处理多文档打印的功能,也就是依次处理多个文件中的每张图形。
目前的想法是最好通过database直接处理,不打开每个文档来操作。
然后自己写了如下代码,可是问题是代码在执行中会在某句话后就会停止。“acPlInfoVdr.Validate(acPlInfo)”在当前文档打印中这句话是没问题的,不知道为什么到了多文档就不可以了。
希望有高手能够帮忙解决这个问题。我目前没有什么好的思路,觉得唯一可能就是因为我处理的打印类型是窗体,所以不适合在database里直接处理。 希望版主们能给我一些思路。
我以前写过一个程序,是删除在特定范围内的实体。在单文档中这个功能可以用selectwindow实现,而我想把这个功能推广到多文档中的时候,也就是希望在database中依次处理每个窗体,发现selectwindow无法使用。后来采用了遍历实体然后判断实体的范围才解决了这个问题。
这次的多文档打印也是处理窗体中的内容,我想这个会不会是与以前做过的那个程序的错误有所关联呢?
希望版主大人可以提供一些资料或方向可供学习,钻研。
我曾经在google里搜索到这篇文章 http://bbs.mjtd.com/forum.php?mod=viewthread&tid=78531。
其实现在的问题就是当时作者用红字所写的如何在database里处理每个文档的打印而不需要打开它?
希望有高手能够指点,共同探讨!
- ' 对指定的文件进行插入操作过程
- Public Function ReadDwgFromFile(ByVal filename As String) As Boolean
- ' 创建集合,定义设计的objectID与点坐标的X与Y值
- Dim ids As New ObjectIdCollection
- Dim idsLine As New ObjectIdCollection
- ' 用来判断是否是A3或A4的左下点坐标
- Dim minX As List(Of Double)
- Dim minY As List(Of Double)
- ' 新建一个数据库对象以读取Dwg文件
- Dim db As New Database()
- Dim ex As Autodesk.AutoCAD.Runtime.Exception
- Try
- ' 如果指定文件名的文件存在,则
- If System.IO.File.Exists(filename) Then
- ' 把文件读入到数据库中
- db.ReadDwgFile(filename, System.IO.FileShare.ReadWrite, True, Nothing)
- Dim pMins As New Point3dCollection
- Dim pMaxs As New Point3dCollection
- minX = New List(Of Double)
- minY = New List(Of Double)
- ' 开始事务处理
- Using trans As Transaction = db.TransactionManager.StartTransaction()
- ' 获取数据库的块表对象
- Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
- ' 打开数据库的模型空间块表记录对象
- Dim btr As BlockTableRecord = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead)
- ' 循环遍历模型空间中的实体
- For Each id As ObjectId In btr
- Dim obj As DBObject = trans.GetObject(id, OpenMode.ForRead)
- If TypeOf (obj) Is DBText Then
- Dim st As DBText = DirectCast(obj, DBText)
- Dim s As String = st.TextString
- If s = "设 计" Then
- ' 将符合条件的文字id加入ids集合中
- ids.Add(id)
- End If
- End If
- If TypeOf (obj) Is Line Then
- Dim ln As Line = DirectCast(obj, Line)
- If ln.StartPoint.X = ln.EndPoint.X Then
- minX.Add(ln.StartPoint.X)
- If ln.StartPoint.Y > ln.EndPoint.Y Then
- minY.Add(ln.EndPoint.Y)
- Else
- minY.Add(ln.StartPoint.Y)
- End If
- End If
- End If
- If TypeOf (obj) Is Polyline Then
- Dim pl As Polyline = DirectCast(obj, Polyline)
- If pl.StartPoint = pl.EndPoint Then
- minX.Add(pl.GeometricExtents.MinPoint.X)
- minY.Add(pl.GeometricExtents.MinPoint.Y)
- End If
- End If
- Next
- ' 根据文件中图的坐标位置排序
- Dim resultIds As ObjectIdCollection = SortImageForTwoV(ids, db)
- Dim num As Integer = 1
- For Each id As ObjectId In resultIds
- Dim obj As DBObject = trans.GetObject(id, OpenMode.ForRead)
- If TypeOf (obj) Is DBText Then
- Dim st As DBText = DirectCast(obj, DBText)
- Dim s As String = st.TextString
- If s = "设 计" Then
- Dim x As Double = st.Position.X
- Dim y As Double = st.Position.Y
- Dim z As Double = st.Position.Z
- Dim h As Double = st.Height
- Dim pointMin As New Point3d(x + h * minX_A3, y + h * minY_A3, z)
- Dim pointMax As New Point3d(x + h * maxX_A3, y + h * maxY_A3, z)
- Dim DwgType As String = "A3"
- For i = 0 To minX.Count - 1
- Dim leftX As Double = minX(i)
- Dim leftY As Double = minY(i)
- If leftX - pointMin.X < 0.2 * h And pointMin.X - leftX < 0.2 * h Then
- If leftY - pointMin.Y < 0.2 * h And pointMin.Y - leftY < 0.2 * h Then
- Exit For
- End If
- End If
- If i = minX.Count - 1 Then
- DwgType = "A4"
- Dim pointMinA4 As New Point3d(x + h * minX_A4, y + h * minY_A4, z)
- Dim pointMaxA4 As New Point3d(x + h * maxX_A4, y + h * maxY_A4, z)
- pointMin = pointMinA4
- pointMax = pointMaxA4
- End If
- Next
- PlotTest(pointMin, pointMax, num, db, filename, DwgType)
- num = num + 1
- End If
- End If
- Next
- While PlotFactory.ProcessPlotState = ProcessPlotState.BackgroundPlotting Or _
- PlotFactory.ProcessPlotState = ProcessPlotState.ForegroundPlotting
- Threading.Thread.Sleep(10)
- Windows.Forms.Application.DoEvents()
- End While
- trans.Commit()
- btr.Dispose()
- bt.Dispose()
- trans.Dispose()
- End Using
- End If
- db.SaveAs(filename, DwgVersion.Current)
- Catch ex
- ' 销毁数据库对象
- db.Dispose()
- Return False
- End Try
- ' 销毁数据库对象
- db.Dispose()
- Return True
- End Function
- Public Sub PlotTest(ByVal pMin As Point3d, ByVal pMax As Point3d, ByVal num As Integer, ByVal db As Database, ByVal filename As String, ByVal DwgType As String)
- Dim ex As Autodesk.AutoCAD.Runtime.Exception
- Dim acCurDb As Database = db
- Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
- Dim acLayout As Layout
- ' 获取数据库的块表对象
- Dim bt As BlockTable = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead)
- ' 打开数据库的模型空间块表记录对象
- Dim btr As BlockTableRecord = acTrans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead)
- acLayout = acTrans.GetObject(btr.LayoutId, OpenMode.ForRead)
- Dim acPlInfo As PlotInfo = New PlotInfo()
- acPlInfo.Layout = acLayout.ObjectId
- Dim acPlSet As PlotSettings = New PlotSettings(True)
- acPlSet.CopyFrom(acLayout)
- Dim acPlSetVdr As PlotSettingsValidator = PlotSettingsValidator.Current
- acPlSetVdr.SetUseStandardScale(acPlSet, True)
- acPlSetVdr.SetStdScaleType(acPlSet, StdScaleType.ScaleToFit) '充满图纸
- acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees090) '纵向打印
- ' 居中打印
- acPlSetVdr.SetPlotCentered(acPlSet, True)
- ' 打印设备和图纸
- acPlSetVdr.SetPlotConfigurationName(acPlSet, "pdfFactory pro", DwgType)
- '先GetPoint然后再GetCorner
- 'Dim pPtRes As PromptPointResult
- 'Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")
- 'pPtOpts.Message = vbLf & "请选择其中一个角点: "
- 'pPtRes = acDoc.Editor.GetPoint(pPtOpts)
- 'Dim PT1 As Point3d = pPtRes.Value
- 'Dim pCnOpts As PromptCornerOptions = New PromptCornerOptions("请选择一个对角点:", PT1)
- 'pPtRes = acDoc.Editor.GetCorner(pCnOpts)
- 'Dim PT2 As Point3d = pPtRes.Value
- Dim PT1 As Point3d = pMin
- Dim PT2 As Point3d = pMax
- '设置打印窗口
- Dim minX As Double = System.Math.Min(PT1.X, PT2.X)
- Dim minY As Double = System.Math.Min(PT1.Y, PT2.Y)
- Dim maxX As Double = System.Math.Max(PT1.X, PT2.X)
- Dim maxY As Double = System.Math.Max(PT1.Y, PT2.Y)
- Dim E2d As Extents2d = New Extents2d(minX, minY, maxX, maxY)
- acPlSetVdr.SetPlotWindowArea(acPlSet, E2d)
- acPlSetVdr.SetPlotType(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotType.Window)
- acPlInfo.OverrideSettings = acPlSet
- Dim acPlInfoVdr As PlotInfoValidator = New PlotInfoValidator()
- acPlInfoVdr.MediaMatchingPolicy = MatchingPolicy.MatchEnabled
- acPlInfoVdr.Validate(acPlInfo)
- Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0)
- While PlotFactory.ProcessPlotState = ProcessPlotState.ForegroundPlotting
- Threading.Thread.Sleep(10)
- End While
- If PlotFactory.ProcessPlotState = Autodesk.AutoCAD.PlottingServices.ProcessPlotState.NotPlotting Then
- Using acPlEng As PlotEngine = PlotFactory.CreatePublishEngine()
- Dim acPlProgDlg As PlotProgressDialog = New PlotProgressDialog(False, 1, True)
- Using (acPlProgDlg)
- acPlProgDlg.PlotMsgString(PlotMessageIndex.DialogTitle) = "打印进度"
- acPlProgDlg.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "取消打印"
- acPlProgDlg.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "打印进度"
- acPlProgDlg.LowerPlotProgressRange = 0
- acPlProgDlg.UpperPlotProgressRange = 100
- acPlProgDlg.PlotProgressPos = 0
- acPlProgDlg.OnBeginPlot()
- acPlProgDlg.IsVisible = True
- acPlEng.BeginPlot(acPlProgDlg, Nothing)
- acPlEng.BeginDocument(acPlInfo, filename, Nothing, 1, True, "c:\Pl" + num.ToString + "")
- 'acPlProgDlg.PlotMsgString(PlotMessageIndex.Status) = "正在打印 " & acDoc.Name & " - " & acLayout.LayoutName
- acPlProgDlg.OnBeginSheet()
- acPlProgDlg.LowerSheetProgressRange = 0
- acPlProgDlg.UpperSheetProgressRange = 100
- acPlProgDlg.SheetProgressPos = 0
- Dim acPlPageInfo As PlotPageInfo = New PlotPageInfo()
- acPlEng.BeginPage(acPlPageInfo, acPlInfo, True, Nothing)
- acPlEng.BeginGenerateGraphics(Nothing)
- acPlEng.EndGenerateGraphics(Nothing)
- acPlEng.EndPage(Nothing)
- acPlProgDlg.SheetProgressPos = 100
- acPlProgDlg.OnEndSheet()
- acPlEng.EndDocument(Nothing)
- acPlProgDlg.PlotProgressPos = 100
- acPlProgDlg.OnEndPlot()
- acPlEng.EndPlot(Nothing)
- End Using
- End Using
- End If
- Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 2)
- End Using
- End Sub
|
|