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