最近在写一个批量分图打印的程序,在研究了kean的打印程序后,总结一下使用NetAPI打印的过程:
1.创建一个plotinfo,然后设置layout属性使其与打印布局空间
2.读取布局的plotsettings对象。先创建一个新的plotsettings,然后使用copyfrom方法由布局空间映射打印设置
3.使用当前的plotsettingsvalidator对plotsettings对象进行自定义设置。plotsettings保存了打印的一些设置,但是plotsettings的属性基本上都是只读的,因此如果我们需要进行自定义设置,必须通过plotsettingsvalidator才能对plotsettings进行有限的操作,其中:
1) GetPlotDeviceList 读取打印机列表
2)GetCanonicalMediaNameList 读取打印机的图纸列表。一般在读取图纸列表之前,我们先使用SetPlotConfigurationName设置打印机,图纸大小设置为null,然后调用RefreshLists刷新图纸列表,然后再进行读取。
3)GetLocaleMediaName 图纸的本地自定义命名。我们会发现GetCanonicalMediaNameList 返回的图纸列表中,用户自定的图纸会以UserDefinedMetric来命名的。而我们的自定义命名只能通过GetLocaleMediaName来读取
4)GetPlotStyleSheetList 读取打印样式表
5)SetPlotConfigurationName 设置打印机及图纸大小
6)SetPlotPaperUnits 设置打印单位。在kean的程序中,SetPlotConfigurationName是最后设置的。但是我们会发现,设置了SetPlotConfigurationName后,打印单位会自动变成了英寸,因此我们需要在SetPlotConfigurationName后调用SetPlotPaperUnits来进行修正。
7)SetCurrentStyleSheet 设置打印样式
8)SetPlotWindowArea 设置打印窗选范围
9)SetPlotType设置打印范围类型。对于窗选打印,应先设置SetPlotWindowArea ,然后再设置SetPlotType,否则有可能会引发错误
10)SetCustomPrintScale 设置自定义打印比例
11)SetClosestMediaName 设置接近的图幅。这个方法的使用暂时不明确,因为每次测试均引发错误
12)SetPlotOrigin 设置打印偏移
13)SetPlotCentered设置居中打印
14)SetStdScaleType 设置标准打印比例。布满图纸打印在这里设置
15)SetStdScale 设置标准打印比例
16)SetUseStandardScale 使用标准打印比例,对于自定义打印比例不需要设置该项,否则可能引发错误
4.通过plotinfo的overridesettings属性将plotinfo与plotsettings关联
5.创建一个plotinfovalidator,使用validate方法将plotinfo激活
6.由plotfactory建立一个plotengine发布引擎,执行打印任务。
打印顺序:
1)BeginPlot
2)BeginDocument
3)BeginPage
4)BeginGenerateGraphics
5)EndGenerateGraphics
6)EndPage
7)EndDocument
8)EndPlot
网友答: 有意思吗,标题上的内容就不放,与题不合。网友答: 本帖最后由 TiStars 于 2018-1-18 10:12 编辑
我狗尾续貂一下:
----------------------------------------------------------------

------------------------------------------------
而且,按照上述操作进行Extents3d转换时,要注意第一个参数的坐标值要小于第二个参数的坐标值。
不过我只知其然而不知其所以然,请高手帮忙解释一下,谢谢。

网友答: 打印这部分因为自己不需要所以一直懒得看,呵呵
欢迎水手多发相关的文章和代码网友答: 我用VBA做过,NET没试过网友答: 期待楼主杰作...网友答: 本帖最后由 雪山飞狐_lzh 于 2011-2-17 18:16 编辑

网友答: 好像和打印无关?
ps:WeltionChen既是水手?网友答: 呵呵,这是打印前期处理,到后面就清楚了网友答: 添加格式后看起来很乱,我一开始也是添加了格式,后来取消的网友答: 图框识别呀,赞一个
俺先慢慢消化,期待楼主下文~~~网友答:
太好了!这个方法有C#版的了,谢谢水老哥!
1.创建一个plotinfo,然后设置layout属性使其与打印布局空间
2.读取布局的plotsettings对象。先创建一个新的plotsettings,然后使用copyfrom方法由布局空间映射打印设置
3.使用当前的plotsettingsvalidator对plotsettings对象进行自定义设置。plotsettings保存了打印的一些设置,但是plotsettings的属性基本上都是只读的,因此如果我们需要进行自定义设置,必须通过plotsettingsvalidator才能对plotsettings进行有限的操作,其中:
1) GetPlotDeviceList 读取打印机列表
2)GetCanonicalMediaNameList 读取打印机的图纸列表。一般在读取图纸列表之前,我们先使用SetPlotConfigurationName设置打印机,图纸大小设置为null,然后调用RefreshLists刷新图纸列表,然后再进行读取。
3)GetLocaleMediaName 图纸的本地自定义命名。我们会发现GetCanonicalMediaNameList 返回的图纸列表中,用户自定的图纸会以UserDefinedMetric来命名的。而我们的自定义命名只能通过GetLocaleMediaName来读取
4)GetPlotStyleSheetList 读取打印样式表
5)SetPlotConfigurationName 设置打印机及图纸大小
6)SetPlotPaperUnits 设置打印单位。在kean的程序中,SetPlotConfigurationName是最后设置的。但是我们会发现,设置了SetPlotConfigurationName后,打印单位会自动变成了英寸,因此我们需要在SetPlotConfigurationName后调用SetPlotPaperUnits来进行修正。
7)SetCurrentStyleSheet 设置打印样式
8)SetPlotWindowArea 设置打印窗选范围
9)SetPlotType设置打印范围类型。对于窗选打印,应先设置SetPlotWindowArea ,然后再设置SetPlotType,否则有可能会引发错误
10)SetCustomPrintScale 设置自定义打印比例
11)SetClosestMediaName 设置接近的图幅。这个方法的使用暂时不明确,因为每次测试均引发错误
12)SetPlotOrigin 设置打印偏移
13)SetPlotCentered设置居中打印
14)SetStdScaleType 设置标准打印比例。布满图纸打印在这里设置
15)SetStdScale 设置标准打印比例
16)SetUseStandardScale 使用标准打印比例,对于自定义打印比例不需要设置该项,否则可能引发错误
4.通过plotinfo的overridesettings属性将plotinfo与plotsettings关联
5.创建一个plotinfovalidator,使用validate方法将plotinfo激活
6.由plotfactory建立一个plotengine发布引擎,执行打印任务。
打印顺序:
1)BeginPlot
2)BeginDocument
3)BeginPage
4)BeginGenerateGraphics
5)EndGenerateGraphics
6)EndPage
7)EndDocument
8)EndPlot
网友答: 有意思吗,标题上的内容就不放,与题不合。网友答: 本帖最后由 TiStars 于 2018-1-18 10:12 编辑
我狗尾续貂一下:
- 如果在模型空间打印,且需要选定范围,根据我自己的经验,选定的坐标不能直接设置给SetPlotWindowArea ,否则打印出来的都是空白,需要按照这里说的作一下转换。
----------------------------------------------------------------

- // Gets the current view
- ViewTableRecord acView = acDoc.Editor.GetCurrentView();
- Extents3d eExtents = new Extents3d(new Point3d(0, 0, 0), new Point3d(630, 445.5, 0));
- // Translates WCS coordinates to DCS
- Matrix3d matWCS2DCS;
- matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection);
- matWCS2DCS = Matrix3d.Displacement(acView.Target - Point3d.Origin) * matWCS2DCS;
- matWCS2DCS = Matrix3d.Rotation(-acView.ViewTwist,
- acView.ViewDirection,
- acView.Target) * matWCS2DCS;
- // Tranforms the extents to DCS
- matWCS2DCS = matWCS2DCS.Inverse();
- eExtents.TransformBy(matWCS2DCS);
- // Defines the area to output
- acPlSetVdr.SetPlotType(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
- acPlSetVdr.SetPlotWindowArea(acPlSet, new Extents2d(eExtents.MinPoint.X, eExtents.MinPoint.Y,
- eExtents.MaxPoint.X, eExtents.MaxPoint.Y));
------------------------------------------------
而且,按照上述操作进行Extents3d转换时,要注意第一个参数的坐标值要小于第二个参数的坐标值。
不过我只知其然而不知其所以然,请高手帮忙解释一下,谢谢。
- 另外还想起来一个,如果把后台打印设为前台,则会大大提高打印速度。

- //保存App的原参数
- short bgPlot =(short)Application.GetSystemVariable("BACKGROUNDPLOT");
- //设定为前台打印,加快打印速度
- Application.SetSystemVariable("BACKGROUNDPLOT", 0);
- 刚刚又遇到一个问题,看了楼主的这一条解决了,不过我没有RefreshLists就可以获取到图纸列表。
2)GetCanonicalMediaNameList 读取打印机的图纸列表。一般在读取图纸列表之前,我们先使用SetPlotConfigurationName设置打印机,图纸大小设置为null,然后调用RefreshLists刷新图纸列表,然后再进行读取。
网友答: 打印这部分因为自己不需要所以一直懒得看,呵呵
欢迎水手多发相关的文章和代码网友答: 我用VBA做过,NET没试过网友答: 期待楼主杰作...网友答: 本帖最后由 雪山飞狐_lzh 于 2011-2-17 18:16 编辑

-
- /// <summary>
- ///首尾相连的线段连接成多段线
- /// V1.0 by WeltionChen @2011.02.17
- /// 实现原理:
- /// 1.选择图面上所有直线段
- /// 2.选取选集第一条直线作为起始线段,向线段的两个方向搜索与之相连的直线段
- /// 3.搜索方式采用Editor的SelectCrossingWindow方法通过线段的端点创建选集
- /// 正常情况下会选到1到2个线段(本程序暂不处理3个线段相交的情况),剔除本身,得到与之相连的直线段
- /// 4.处理过的直线段将不再作为起始线段,由集合中剔除
- /// 4.通过递归循环依次搜索,直到末端。
- /// 5.删除原线段,根据创建多段线
- /// 6.循环处理所有的线段
- /// </summary>
- [CommandMethod ("tt5")]
- public void JionLinesToPline()
- {
- //选择图面上所有直线段
- Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
- SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "Line") });
- PromptSelectionResult selectLinesResult = ed.SelectAll(sf);
- if (selectLinesResult.Status != PromptStatus.OK)
- return;
- //需要处理的直线段集合
- List<ObjectId> lineObjectIds = new List<ObjectId>(selectLinesResult.Value.GetObjectIds());
- using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
- {
- Database db = HostApplicationServices.WorkingDatabase;
- BlockTableRecord currentSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
- while (true)
- {
- //选取选集第一条直线作为起始线段
- ObjectId currentLineId = lineObjectIds[0];
- //处理过的直线段将不再作为起始线段,由集合中剔除
- lineObjectIds.RemoveAt(0);
- Line currentLine = tr.GetObject(currentLineId, OpenMode.ForWrite) as Line;
- //多段线的顶点集合,由各段相连的直线段的端点组成,初始值为起始线段的端点
- List<Point3d> plinePoints = new List<Point3d> { currentLine.StartPoint, currentLine.EndPoint };
- //每个直线段有两个方向,由起点向终点方向搜索
- JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, currentLineId, currentLineId);
- //翻转点集
- plinePoints.Reverse();
- //由终点向起点方向搜索
- JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, currentLineId, currentLineId);
- //本程序为将相连的直线段转成多段线,所以对孤立的直线段不做处理
- if (plinePoints.Count > 2)
- {
- //创建多段线
- Autodesk.AutoCAD.DatabaseServices.Polyline resultPline = new Autodesk.AutoCAD.DatabaseServices.Polyline();
- for (int i = 0; i < plinePoints.Count-1; i++)
- {
- resultPline.AddVertexAt(i, new Point2d(plinePoints.X, plinePoints.Y), 0, 0, 0);
- }
- if (plinePoints[0] == plinePoints[plinePoints.Count - 1])
- {
- resultPline.Closed = true;
- }
- else
- {
- resultPline.AddVertexAt(plinePoints.Count - 1, new Point2d(plinePoints[plinePoints.Count - 1].X, plinePoints[plinePoints.Count - 1].Y), 0, 0, 0);
- }
- resultPline.Layer = currentLine.Layer;
- resultPline.Linetype = currentLine.Linetype;
- resultPline.LinetypeScale = currentLine.LinetypeScale;
- currentSpace.AppendEntity(resultPline);
- tr.AddNewlyCreatedDBObject(resultPline, true);
- //删除起始直线段
- currentLine.Erase();
- }
- //处理完毕,跳出循环
- if (lineObjectIds.Count == 0)
- break;
- }
- tr.Commit();
- }
- }
- /// <summary>
- /// 线段连接成多段线递归循环部分
- /// V1.0 by WeltionChen @2011.02.17
- /// </summary>
- /// <param name="lineObjectIds">线段的objectid集合</param>
- /// <param name="tr">transaction</param>
- /// <param name="plinePoints">多段线顶点坐标,也是各线段的端点坐标集合</param>
- /// <param name="currentLineId">当前线段的objectid</param>
- void JionLinesToPline(ref List<ObjectId> lineObjectIds, Transaction tr, ref List<Point3d> plinePoints, ObjectId currentLineId, ObjectId startLineId)
- {
- //提取端点
- Point3d lastPoint = plinePoints[plinePoints.Count - 1];
- Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
- SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "Line") });
- //通过点创建选集
- PromptSelectionResult selectLinesResult = ed.SelectCrossingWindow(lastPoint, lastPoint, sf);
- if (selectLinesResult.Status == PromptStatus.OK)
- {
- List<ObjectId> selectedLinesId = new List<ObjectId>(selectLinesResult.Value.GetObjectIds());
- //剔除本身
- selectedLinesId.Remove(currentLineId);
- //处理相连的直线段
- if (selectedLinesId.Count == 1)
- {
- ObjectId selectedLineId = selectedLinesId[0];
- //处理过的直线段将不再作为起始线段,由集合中剔除
- if (selectedLineId != startLineId)
- {
- lineObjectIds.Remove(selectedLineId);
- Line selectedLine = tr.GetObject(selectedLineId, OpenMode.ForWrite) as Line;
- //添加顶点
- if (selectedLine.StartPoint == lastPoint)
- {
- plinePoints.Add(selectedLine.EndPoint);
- }
- else
- {
- plinePoints.Add(selectedLine.StartPoint);
- }
- //递归继续搜索
- JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, selectedLineId, startLineId);
- //删除中间线段
- selectedLine.Erase();
- }
- }
- }
- }
网友答: 好像和打印无关?
ps:WeltionChen既是水手?网友答: 呵呵,这是打印前期处理,到后面就清楚了网友答: 添加格式后看起来很乱,我一开始也是添加了格式,后来取消的网友答: 图框识别呀,赞一个
俺先慢慢消化,期待楼主下文~~~网友答:
太好了!这个方法有C#版的了,谢谢水老哥!