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