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