问题描述: 

在一些比较常见的出图常见中,将多个图框打印到同一个PDF中,目前大部分示例都是单图框打印成单PDF,那么如何打印到同一个PDF文件中呢?

示例代码:

#include "stdafx.h"
#include "Plot.h"


/// <summary>
/// 通过布局管理器获取当前布局Id
/// </summary>
/// <param name="activeLayoutBTRId">活动Layout块表记录Id</param>
/// <returns>当前布局Id</returns>
ZcDbObjectId getLayoutId(const ZcDbObjectId activeLayoutBTRId)
{
	ZcDbBlockTableRecord* pBlkTblRec = NULL;
	auto es = zcdbOpenObject(pBlkTblRec, activeLayoutBTRId);
	if (es != Zcad::eOk)
	{
		zds_alert(L"获取当前布局块表记录失败");
		zds_printf(L"\nerror code : %s\n", zcadErrorStatusText(es));
		if (pBlkTblRec != NULL) pBlkTblRec->close();
		return ZcDbObjectId::kNull;
	}
	auto pLayoutId = pBlkTblRec->getLayoutId();
	pBlkTblRec->close();
	return pLayoutId;
}


/// <summary>
/// 设置打印配置
/// </summary>
/// <param name="pLayoutId">当前布局Id</param>
/// <param name="plotInfo">打印信息</param>
/// <returns></returns>
bool setPlotConfig(const ZcDbObjectId pLayoutId, ZcPlPlotInfo& plotInfo)
{
	ZcDbLayout* pLayout = NULL;
	auto es = zcdbOpenObject(pLayout, pLayoutId);
	if (es != Zcad::eOk)
	{
		zds_alert(L"获取布局对象失败");
		zds_printf(L"\nerror code : %s\n", zcadErrorStatusText(es));
		if (pLayout != NULL) pLayout->close();
		return false;
	}
	ZcDbPlotSettings* pPlotSettings = new ZcDbPlotSettings(pLayout->modelType());
	pPlotSettings->copyFrom(pLayout);
	pLayout->close();

	ZcDbPlotSettingsValidator* pPSV = NULL;
	pPSV = zcdbHostApplicationServices()->plotSettingsValidator();

	//更新打印设备列表,以获取当前能够使用的打印配置
	pPSV->refreshLists(pPlotSettings);

	/*
	* 自定义打印机配置
	* 如果是多个dwg打印到同一个pdf中,必须保证每次输出的设备都相同
	*/
	pPSV->setPlotCfgName(pPlotSettings, L"DWG to PDF.pc5");
	pPSV->setCanonicalMediaName(pPlotSettings, L"ISO A4");
	pPSV->setPlotType(pPlotSettings, ZcDbPlotSettings::kExtents);
	pPSV->setCurrentStyleSheet(pPlotSettings, L"zwcad.ctb");
	pPSV->setPlotCentered(pPlotSettings, true);
	pPSV->setUseStandardScale(pPlotSettings, true);
	pPSV->setStdScaleType(pPlotSettings, ZcDbPlotSettings::kScaleToFit);
	pPSV->setPlotRotation(pPlotSettings, ZcDbPlotSettings::k90degrees);

	plotInfo.setOverrideSettings(pPlotSettings);
	pPlotSettings->close();
	return true;
}


/// <summary>
/// 打印入口函数
/// </summary>
/// <param name="pdfPath">输出pdf的路径</param>
void Sample_plot(const CString pdfPath)
{
	ZcPlPlotEngine* pEngine = NULL;
	auto es = ZcPlPlotFactory::createPublishEngine(pEngine);
	if (es != Zcad::eOk)
	{
		zds_alert(L"创建打印程序失败!");
		zds_printf(L"\nerror status: %s\n", zcadErrorStatusText(es));
		if (pEngine != NULL) pEngine->destroy();
		return;
	}
	
	es = pEngine->beginPlot(NULL);
	if (es != Zcad::eOk)
	{
		zds_alert(L"开始打印失败");
		zds_printf(L"\nerror status: %s\n", zcadErrorStatusText(es));
		if (pEngine != NULL) pEngine->destroy();
		return;
	}

	ZcDbLayoutManager* pLayoutMgr = zcdbHostApplicationServices()->layoutManager();
	ZcPlPlotInfo plotInfo;
	ZcPlPlotPageInfo pageInfo;

	auto doc_Iter = zcDocManager->newZcApDocumentIterator();
	bool bHasDocument = false;

	for (; !doc_Iter->done(); doc_Iter->step())
	{
		/*
		* 切换当前激活文档以获取布局
		*/
		zcDocManager->activateDocument(doc_Iter->document());

		auto curLayoutId = getLayoutId(pLayoutMgr->getActiveLayoutBTRId());
		if (curLayoutId == ZcDbObjectId::kNull)
		{
			return;
		}
		plotInfo.setLayout(curLayoutId);

		/*
		* 自定义当前图纸的打印配置
		*/
		if (!setPlotConfig(curLayoutId, plotInfo))
		{
			return;
		}

		/*
		* 创建打印信息验证器
		*/
		ZcPlPlotInfoValidator pPIV;
		pPIV.setMediaMatchingPolicy(ZcPlPlotInfoValidator::kMatchEnabled);
		es = pPIV.validate(plotInfo);

		/*
		* 打印一份文档只需要执行一次beginDocument
		*/
		if (!bHasDocument)
		{
			es = pEngine->beginDocument(plotInfo, doc_Iter->document()->fileName(), NULL, 1, true, pdfPath);
			bHasDocument = true;
		}

		/*
		* 开始打印
		*/
		es = pEngine->beginPage(pageInfo, plotInfo, true);
		es = pEngine->beginGenerateGraphics();
		es = pEngine->endGenerateGraphics();
		es = pEngine->endPage();
	}

	/*
	* 结束打印,销毁打印进程,避免影响其他打印进程执行
	*/
	es = pEngine->endDocument();
	es = pEngine->endPlot();
	pEngine->destroy();

	delete doc_Iter;
	zds_printf(L"\n打印完成\n");
}


该示例是将多个布局打印到一个PDF中。

拓展:

还有一个很常见场景是一个模型空间有多个“图框”如何循环打印?

示例代码是循环打印了多个布局,循环多个图框的关键在于找出图框坐标点,循环图框信息用窗口打印。

难点是如何准确找到图框坐标点,这里提供几个思路:

图框判断:

1.图框上面有没有什么字段信息可以读取判断是A2还是A3A4

2.通过图框的长宽尺寸判断是A几

3.最简单的方法是图框能不能重命名一下直接命名成_A3 _A4后缀的图块,一般机械图框命名都会带*A字样。

最后选用“zcWindow”模式遍历图框块分别获取打印范围依次打印。


英文空间链接


★中望CAD二次开发如何循环打印多页到同一个PDF文件?https://confluence.zwcad.com/pages/viewpage.action?pageId=301140569

  • No labels