Fenix1986 发表于 2010-6-2 09:51:00

[求助]多文档打印

本帖最后由 作者 于 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
页: [1]
查看完整版本: [求助]多文档打印