tieque 发表于 2020-11-1 21:32:16

CAD快速打印(批量打印)PDF/DWF/JPG/PNG-特色:自适应图纸尺寸

本帖最后由 tieque 于 2020-12-7 19:58 编辑

CAD快速打印(批量打印)PDF/DWF/JPG/PNG-特色:自适应图纸尺寸、纯命令操作

2020.12.7 日更新:增加对CAD2019、CAD2017、CAD2015;2020.12.5 日更新:增加对CAD2021、CAD2018、CAD2016、CAD2014的支持;2020.11.24 日更新:1.修复若干问题。2.增加批量打印布局的功能1.    支持CAD2021、CAD2020、CAD2019、CAD2018、CAD2017、CAD2016、CAD2015、CAD2014;2.    命令栏输入 qq 启动打印程序;3.    支持动态块图框、“TK”图层图框、柱状图图框、任意实体组成的范围;4.    多段线组成的图框:图框位于tk,TK,Tk,tK,图框,DZ图框,*图框*等图层上,多段线顶点数量为4且闭合;5.    支持批量打印地质柱状图,请先炸开柱状图头部,再进行打印(可使用“zzt”命令可将柱状图从左到右,从上到下排序,每行10个柱状图);6.    支持任意尺寸的图纸;7.    同一个DWG文件中可批量打印或者单独打印:a.批量打印需提前设置好图框; b.打印单幅不需要设置图框,框选所要打印内容即可;8.    可打印PDF、DWF、 JPG 、PNG、 TIFF,打印机各项设置可根据提示进行操作,程序能记忆上一次的设置参数;9.    打印完成的文件与DWG文件放在同一个文件夹内。对于未保存的DWG,与“xllTriangle_ARX.arx”文件放在一处;10.    目前处于测试阶段,如有问题请反馈至925674203@qq.com、QQ群:1148455637感谢诸多技术大神给与的支持!



以下为部分代码:

static void QuickPlot_ARX_QQ()
{
    acutPrintf(_T("\n功能:QQ-快速打印等.\n"));
    acutPrintf(_T("\n感谢诸多技术大神给与的支持!\n"));
    acutPrintf(_T("\n作者:徐二亮,如有问题请反馈至925674203@qq.com、QQ群:1148455637.\n"));   

    //获得当前dwg文件所在路径
    CString dwgfullpath, dwgfilename;
    GetcurDocumentfilePathName(dwgfullpath, dwgfilename);

    //获取选择集的包围盒
    long length;
    ads_name ss0;

    //获得当前图形窗口中已经选择的实体(PickFirst 选择集)
    if (RTNORM == acedSSGet(_T("I"), NULL, NULL, NULL, ss0))
    {
      if (RTNORM != acedSSLength(ss0, (Adesk::Int32*)&length)) return;      
    }
    else
    {
      TCHAR *promptStr;
      promptStr = _T("请选择打印范围:");
      promptStr = _T("");
      if (RTNORM != acedSSGet(_T(":$"), promptStr, NULL, NULL, ss0))
      {
      acutPrintf(_T("\n神马都没有选中...,已退出。"));
      return;
      }
      if (RTNORM != acedSSLength(ss0, (Adesk::Int32*)&length)) return;
      
      acedSSSetFirst(ss0, NULL);//亮显对象
    }
    //acutPrintf(_T("\n已选择实体数量: %d"), length);   

    //打印参数
    int nPX = 1;
    int plotDeviceName = 0;//打印机名称
    PlotRotation rotationType = AcDbPlotSettings::k0degrees;//旋转方向
    ACHAR * styleSheetName = _T("monochrome.ctb");//样式表
    REAL scale = 1.0;//打印比例
    //设置打印参数
    if (PlotSettings(plotDeviceName, rotationType, styleSheetName, scale) == 0) return;   

    //开始计时
    clock_t start(clock()), end;
    start = clock();

    AcDbObjectId objId;
    AcDbExtents extent;
    AcDbExtents extentsel;//选择集的包围盒,选择用
    for (int i = 0; i < length; i++)
    {
      ads_name ent;
      acedSSName(ss0, i, ent);
      acdbGetObjectId(objId, ent);//获得指定元素的ObjectId

      AcDbEntity *pEnt = NULL;
      if (acdbOpenObject(pEnt, objId, AcDb::kForRead) == Acad::eOk)
      {
      pEnt->getGeomExtents(extent);
      extentsel.addExt(extent);
      }
      pEnt->close();
    }
    acedSSFree(ss0); // 删除选择集

    AcGePoint3d ptmin, ptmax;
    ptmin = extentsel.minPoint();
    ptmax = extentsel.maxPoint();

    ads_point adsptmin, adsptmax;
    adsptmin = ptmin.x - 0.1;
    adsptmin = ptmin.y - 0.1;
    adsptmax = ptmax.x + 0.1;
    adsptmax = ptmax.y + 0.1;

    //acutPrintf(_T("\n选择集范围: "));
    //acutPrintf(_T("\nminx: %f"), ptmin.x);
    //acutPrintf(_T("\tminy: %f"), ptmin.y);
    //acutPrintf(_T("\nmaxx: %f"), ptmax.x);
    //acutPrintf(_T("\tmaxy: %f"), ptmax.y);

    vector<CString> pdfname;//存储文件名称
    vector<AcDbExtents> extentvec;//存储图框范围
    vector<AcDbExtents> extentvecsort;
    vector<AcDbExtents> extentvectmp;

    //选择柱状图
    long lengthZZT = 1;
    lengthZZT = SelectZZT(adsptmin, adsptmax, extentvec, pdfname);

    //选择动态块图框
    long lengthDTK = 1;
    lengthDTK = SelectDynamicBlockTK(adsptmin, adsptmax, extentvecsort, extentvectmp);   
   
    //选择图层"tk"上的闭合多段线
    long lengthYTK = 1;
    lengthYTK= SelectLayerTKPolyLineTK(adsptmin, adsptmax, extentvecsort, extentvectmp);
   
    //去除重复图框、大图框里的小图框
    long lengthDTKYKR = 0;   
    if (lengthDTK + lengthYTK > 0)//判断“回”形图框情况:删除大图框里的小图框,只保留最大的图框
    {
      lengthDTKYKR = RemoveOverLayandsmallInBigTK(extentvecsort, extentvectmp, extentvec, pdfname);
    }
    extentvecsort.clear();
    extentvecsort.shrink_to_fit();
    extentvectmp.clear();
    extentvectmp.shrink_to_fit();

    //如果没有上述任何一种情况,则按照选择集范围打印
    if (extentvec.size() == 0)
    {
      extentvec.push_back(extentsel);
      pdfname.push_back("");

      acutPrintf(_T("\n未识别到任何图框,正在使用选择集范围进行打印!"));
    }
    acutPrintf(_T("\n识别柱状图%d 个,动态块图框+多段线图框 %d 个,共 %d 个。"), lengthZZT, lengthDTKYKR, extentvec.size());

    //设置打印纸张   
    vector<string> vecMediaName;//存储所有纸张
    vector<AcDbExtents>extentPiaNode;//存储所有需要加入PMP的打印范围

    //优先使用系统纸张,以加快打印速度
    //确定打印所需的系统内置纸张
    //确定需要向PMP添加的纸张及其数量
    GetcanonicalMediaNames(plotDeviceName ,extentvec, vecMediaName, extentPiaNode);

    //用自定义纸张替换上一步中名称为-1的纸张
    string spixelormm = "_毫米)";
    string sudmMetricRaster = "UserDefinedMetric_(";

    //TIFF Version 6 (不压缩).pc3、PublishToWeb JPG.pc3、PublishToWeb PNG.pc3
    PlotPaperUnits units = AcDbPlotSettings::kMillimeters;
    if (plotDeviceName == 2 || plotDeviceName == 3 || plotDeviceName == 4)
    {
      spixelormm = "_像素)";//像素
      sudmMetricRaster = "UserDefinedRaster_(";
      units = AcDbPlotSettings::kPixels;
      nPX = 30;
    }

    for (int i = 0; i < extentvec.size(); i++)
    {
      if (vecMediaName != "-1") continue;

      extent = extentvec;
      ptmin = extent.minPoint();
      ptmax = extent.maxPoint();

      int PaperX = (int)(ptmax.x - ptmin.x)*nPX;
      int PaperY = (int)(ptmax.y - ptmin.y)*nPX;

      string sPaperX = to_string(PaperX) + ".00";
      string sPaperY = to_string(PaperY) + ".00";

      vecMediaName= sudmMetricRaster + sPaperX + "_x_" + sPaperY + spixelormm;
    }
   
    //根据PC3文件生成PMP文件,将自定义图纸vecPiaNode加入其中
    //将pc3文件中user_defined_model_pathname修改为新PMP的路径
    if (readPC3andCreatePMP(extentPiaNode, plotDeviceName, nPX) == "err")
    {
      acutPrintf(_T("readPC3andCreatePMP() err!\n"));
      return;
    }


    //每当通过 plot API 访问绘图引擎时,如果将 BACKGROUNDPLOT 系统变量设置为0,则系统将在前台进行绘制;
    //如果将 BACKGROUNDPLOT 系统变量设置为1,2或3,则系统将在后台进行绘制。
    //acedSetEnv(L"BACKGROUNDPLOT", L"0");
    acutPrintf(_T("\n"));
    acedCommandS(RTSTR, L"BACKGROUNDPLOT", RTSTR, L"0", RTNONE);
    acutPrintf(_T("\n"));

    //设置当前图形的图形单位(英制或公制),0为英制,1为公制
    //acedSetEnv(L"MEASUREMENT", L"1");
    acutPrintf(_T("\n"));
    acedCommandS(RTSTR, L"MEASUREMENT", RTSTR, L"1", RTNONE);
    acutPrintf(_T("\n"));
   
    ACHAR* sDevice;
    CString CSext = ".pdf";

    if (plotDeviceName == 0) {
      sDevice = _T("DWG To PDF.pc3");
      CSext = ".pdf";
    }
    if (plotDeviceName == 1){
      CSext = ".dwf";
      sDevice = _T("DWF6 ePlot.pc3");
    }
    if (plotDeviceName == 2){
      CSext = "";
      sDevice = _T("TIFF Version 6 (不压缩).pc3");
    }
    if (plotDeviceName == 3){
      CSext = "";
      sDevice = _T("PublishToWeb JPG.pc3");
    }
    if (plotDeviceName == 4){
      CSext = "";
      sDevice = _T("PublishToWeb PNG.pc3");
    }

    //打印      
    acedSetStatusBarProgressMeter(TEXT("正在打印..:"), 0, (int)extentvec.size() - 1);//进度条
    for (int i = 0; i < extentvec.size(); i++)
    {
      //按esc,停止打印
      if (acedUsrBrk())break;

      CString snum;
      snum.Format(_T("%d"), i+1);

      CString fullpathPDFname = dwgfullpath+"_"+ snum + pdfname + CSext;

      extent = extentvec;
      ptmin = extent.minPoint();
      ptmax = extent.maxPoint();

      REAL paperWidth = ptmax.x - ptmin.x;
      REAL paperHeight = ptmax.y - ptmin.y;
      
      ACHAR * MediaName;
      CConvertUtil::StringToWchar_t(MediaName, vecMediaName);

      Acad::ErrorStatus es = PlottoFile(sDevice, MediaName, rotationType, styleSheetName,
      scale, units, ptmin, ptmax, fullpathPDFname);

      if (es != Acad::eOk)
      {
      continue;
      }

      acutPrintf(_T("\n已完成打印:%s\n"), fullpathPDFname);

      // 控制进度条当前进度位置   
      acedSetStatusBarProgressMeterPos(i);
    }   
    acedRestoreStatusBar();// 还原状态栏之前的样子

    extentvec.clear();
    extentvec.shrink_to_fit();

    pdfname.clear();
    pdfname.shrink_to_fit();
    vecMediaName.clear();
    vecMediaName.shrink_to_fit();
    extentPiaNode.clear();
    extentPiaNode.shrink_to_fit();

    //结束计时
    end = clock();
    acutPrintf(_T("\n打印时间:%.5f"), (((REAL)(end - start)) / CLOCKS_PER_SEC));

    acutPrintf(_T("\n作者:徐二亮,如有问题请反馈至925674203@qq.com、QQ群:1148455637.\n"));
}


其他功能如下:

//三角剖分+插值
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, Triangle_ARX, _tri, tri, ACRX_CMD_MODAL, NULL)

//观测点、地层产状及节理产状上图
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, InsertBlk_ARX, _DZ, DZ, ACRX_CMD_MODAL, NULL)

//钻探孔及静探孔上图
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, InsertBlk_ARX, _ZT, ZT, ACRX_CMD_MODAL, NULL)

//危岩点上图
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, InsertBlk_ARX, _WY, WY, ACRX_CMD_MODAL, NULL)

//打开观测点图片
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, CheckGCD_ARX, _CG, CG, ACRX_CMD_MODAL, NULL)

//打开危岩落石图片
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, CheckGCD_ARX, _CW, CW, ACRX_CMD_MODAL, NULL)

//在布局视图中旋转地质块,使之与布局扭转角度一致
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, RotateBlock_ARX, _RB, RB, ACRX_CMD_MODAL, NULL)

//根据路基断面里程,在平面图中绘制垂直线路的断面线
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, Drawverticalline_ARX, _DVL, DVL, ACRX_CMD_MODAL, NULL)

//根据路基横断面里程,在纵断上卡出横断面位置
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, Drawverticalline_ARX, _DVH, DVH, ACRX_CMD_MODAL, NULL)

//获取钻孔的里程及偏距
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, GetMileageOffset_ARX, _MO, MOB, ACRX_CMD_MODAL, NULL)


//重新排列地质柱状图
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, ReRrrangeZZT_ARX, _RRZZT, RRZZT, ACRX_CMD_USEPICKSET | ACRX_CMD_REDRAW | ACRX_CMD_MODAL, NULL)

//获取地质柱状图信息
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, GetZZTInformation_ARX, _ZZTI, ZZTI, ACRX_CMD_MODAL, NULL)

//清理线位:只保留里程、刻度线及中线
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, ClearTherailway_ARX, _CLRW, CLRW, ACRX_CMD_MODAL, NULL)

//快速打印
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, QuickPlot_ARX, _QQ, QQ, ACRX_CMD_USEPICKSET | ACRX_CMD_REDRAW | ACRX_CMD_MODAL, NULL)

//快速打印:解压与压缩测试 zlib
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, QuickPlot_zlib_ARX, _zlib, zlib, ACRX_CMD_MODAL, NULL)

//根据地形图及剖面线提取剖面
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, GetSingleComlexPouMian_ARX, _PM, PM, ACRX_CMD_MODAL, NULL)

//线路折图
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, GetFoldedDrawings_ARX, _FD, FD, ACRX_CMD_MODAL, NULL)

//根据路基段落里程,筛选出范围内中桩高程及轨面高程
ACED_ARXCOMMAND_ENTRY_AUTO(CTriangle_ARXApp, DivideHeight_ARX, _DH, DH, ACRX_CMD_MODAL, NULL)




czb203 发表于 2020-11-2 17:16:58


,可以和MSTEEL批量打印对比一下

yjtdkj 发表于 2020-11-2 12:36:31

,可以和MSTEEL批量打印对比一下

szhorse 发表于 2020-11-6 22:19:19

感谢,先收藏,过几天闲了测试

KMCM_JET 发表于 2020-11-18 14:31:43

本帖最后由 KMCM_JET 于 2020-11-18 14:49 编辑

测试一下,谢谢分享

tieque 发表于 2020-11-18 15:48:53

KMCM_JET 发表于 2020-11-18 14:31
测试一下,谢谢分享

..... 一直是致命错误?

tieque 发表于 2020-11-18 15:50:51

有问题请加群反馈啊 QQ群:1148455637

KMCM_JET 发表于 2020-11-20 14:11:30

tieque 发表于 2020-11-18 15:48
..... 一直是致命错误?

除了你的测试例子外,都是致命错误,不知是我用天正打开的过还是其他操作不当

tieque 发表于 2020-11-21 11:50:18

KMCM_JET 发表于 2020-11-20 14:11
除了你的测试例子外,都是致命错误,不知是我用天正打开的过还是其他操作不当

发我一个看看吧 925674203@qq.com

陈伟 发表于 2021-3-8 11:34:51

希望支持PdfFactory虚拟打印机
页: [1] 2
查看完整版本: CAD快速打印(批量打印)PDF/DWF/JPG/PNG-特色:自适应图纸尺寸