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;
        }    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM