objectARX2010及其以上版本使用publish打印(发布)图纸,后台布局打印图纸例子浅析

AutoCAD 2010版本开始新增了一个发布图纸的功能,可以后台打印图纸,以下是ADN官方博客例子浅析

原文地址 https://adndevblog.typepad.com/autocad/2016/01/create-multi-sheet-pdf-from-arx-using-dsd.html 

先加入相关的头文件和库文件

//添加头文件和库CAD2010及其以上新增
#if _MSC_VER == 1500
#include "acplmisc.h"
#pragma comment(lib,"AcPublish.lib")
#else if _MSC_VER > 1500
#include "acplmisc.h"
#pragma comment(lib,"AcPublish_crx.lib")
#endif

函数主体

//数据可以是后台数据库,但是一定是保存了的数据库,不能是临时数据库
	static void plot (AcDbDatabase *pDb)
	{
		//设置pdf保存路径
		CString pdfPath = _T("d:\\myPDF.pdf");
		//设置打印机设备名
		CString deviceName =  _T("DWG To PDF.pc3");
		Acad::ErrorStatus es = Acad::eOk;

		const TCHAR *docName;
		//获取数据的路径和文件名,注意pdb如果是当前文件,
		//一定要保存后再打印,否者这个路径可能是临时文件
		//pDb即使的后台数据库依然能打印
		es = pDb->getFilename(docName);   

		//获取ACAD应用程序布局管理器
		AcDbLayoutManager *layoutManager = acdbHostApplicationServices()->layoutManager();
		AcDbDictionary *layoutDict = NULL;
		//获取数据库的布局词典
		es = pDb->getLayoutDictionary(layoutDict, AcDb::kForRead);

		//开始收集DSD数据的信息
		// Start collecting info for the DSD data
		AcPlDSDEntries dsdEntries;

		//迭代器遍历布局词典
		AcDbDictionaryIterator *layoutIterator = layoutDict->newIterator();

		//如果我们只想打印图纸空间而不是模型布局,获取pDb模型空间的ID
		// If we only want to plot paper spaces and not the model layout
		AcDbObjectId msId = acdbSymUtil()->blockModelSpaceId(pDb);
		
		for (; layoutIterator && !layoutIterator->done(); layoutIterator->next())
		{
			AcDbObjectPointer<AcDbLayout> layout(layoutIterator->objectId(), AcDb::kForRead); 
			//跳过模型空间
			if (layout->getBlockTableRecordId() == msId)
				continue;

			//!!!注意,布局的打印设置要提前设置好,如纸张,打印线型,等
			//布局使用的是保存的布局的页面设置,也可以设置窗口打印和区域等
			//此处是读模式,是不能修改layout设置
			const ACHAR *layoutName;
			layout->getLayoutName(layoutName);		
			//测试,修改输出的标题名加前缀,pdf单页模式会作为文件名
			CString strPre=_T("sk_");
			strPre+= layoutName ;
			const ACHAR *szOutLayoutName = (LPCTSTR)strPre;
			//设置DSD条目
			AcPlDSDEntry dsdEntry;

			dsdEntry.setLayout(layoutName);
			dsdEntry.setDwgName(docName);
			//测试 此处修改dsdEntry.setTitle(layoutName);
			//条目标题,单页pdf会使用这个名字来保存文件名
			//并且条目的标题如果相同,原有的条目可能会被覆盖
			dsdEntry.setTitle(szOutLayoutName);
			//添加条目到dsd条目集合
			dsdEntries.append(dsdEntry);     
		}
		//删除(释放)布局遍历迭代器
		delete layoutIterator; 
		layoutDict->close();

		//将dsd条目添加到dsd数据
		AcPlDSDData dsdData;
		dsdData.setDSDEntries(dsdEntries); 

		//设置dsd数据项目路径
		dsdData.setProjectPath(_T("d:\\"));
		//设置dsd数据的日志路径,pdf打印机可能无效,没有生成日志
		dsdData.setLogFilePath(_T("d:\\logdwf.log"));

		//设置单页还是多页,如果是单页,将会使用布局名来保存文件名
		//kSinglePDF kMultiPDF
		dsdData.setSheetType(AcPlDSDEntry::kMultiPDF);
		//设置打印的份数,这个pdf打印机不能设置,始终是1
		dsdData.setNoOfCopies(1);
		//设置目标名,保存的文件名(单页无效)
		dsdData.setDestinationName(pdfPath);
		//设置提示输入dwf名,如果为true可能会提示输入文件名
		dsdData.setPromptForDwfName(false);
		//设置图纸集的名字,这个会显示在打印和发布详细信息中
		dsdData.setSheetSetName(_T("PublisherSet"));

		//设置当前配置和打印设备名
		AcPlPlotConfig *plotConfig;
		acplPlotConfigManager->setCurrentConfig(plotConfig, deviceName);    
		
		
		//后面的acplPublishExecute需要加载AcPublish.arx
		// We need this for acplPublishExecute 
		acedArxLoad(_T("AcPublish.arx")); 

		//可能需要#include "acplmisc.h"
		//可能需要2010-2012#pragma comment(lib,"AcPublish.lib")
		//可能需要2013及其以上#pragma comment(lib,"AcPublish_crx.lib")
		//执行发布程序
		acplPublishExecute(dsdData, plotConfig, false);
	}

  测试代码

        //如果使用当前数据库,一定要保存文件否则会出错,
        //当前数据库有自动保存操作,即使不操作,如果不保存,也会出错。
        //plot(acdbHostApplicationServices()->workingDatabase());
        AcDbDatabase *pDb=new AcDbDatabase();
        pDb->readDwgFile(_T("D:\\TestPublish.dwg"));
        plot(pDb);
        if (pDb!=NULL)
        {
            delete pDb;
            pDb=NULL;
        }    

猜你喜欢

转载自www.cnblogs.com/edata/p/11015514.html
今日推荐