在实际CAD二次开发种遇到了需要自定义纸张的问题,CAD本身没有自定义纸张的api,需要对pmp文件做一些操作,再次,致敬惊惊大佬的博客,才让我这方面的开发工作量减少了很多,靠我自己也一时半会解决不了,因为我是用CAD2020版本来做这个的我对惊佬的两个重要的类做了一部分更改。

 public class CreatePMP
 {
     public Dictionary<string,string> hdiDict = new Dictionary<string,string>();
     public string Path_pmp { set; get; }
     public string Path_pc3 { set; get; }
     public string Dwgtopdf { get; set; } = "DWG To PDF";
     public string DwgtopdfPC3
     {
         get
         {
             return Dwgtopdf + ".pc3";
         }
     }
     /// <summary>
     /// 创建pmp文件
     /// </summary>    
     public CreatePMP(string style)
     {
         InitDict();
         Dwgtopdf = style;
         //pc3打印机位置
         //string plottersPath = CadSystem.Getvar("PrinterConfigDir") + "\\";
         string plottersPath = "";
         var devices = PlotConfigManager.Devices;
         string fullPath = "";
         for (int i = 0; i < devices.Count; i++)
         {
             if (devices[i].DeviceName.Contains(style))
             {
                 plottersPath = Path.GetDirectoryName(devices[i].FullPath) + "\\";
                 fullPath = devices[i].FullPath;
             }
         }

         Path_pc3 = plottersPath + DwgtopdfPC3;
         if (!File.Exists(Path_pc3))
         {
             return;
         }
         //驱动位置
         string drvFilePath = "";
         //string acaddrv = 
         var acaddrv = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Drv");
         {
             var theFolder = new DirectoryInfo(acaddrv);
             if (!theFolder.Exists)
                 return;
             //遍历文件 
             foreach (FileInfo nextFile in theFolder.GetFiles())
             {
                 //if (nextFile.Extension.ToUpper() == ".HDI" && nextFile.Name.Contains("pdfplot"))
                 if (nextFile.Extension.ToUpper() == ".HDI" && nextFile.Name.Contains(hdiDict[style]))
                 {
                     drvFilePath = nextFile.FullName;
                     break;
                 }
             }
         }

         var pmpfiles = plottersPath + "PMP Files";
         Directory.CreateDirectory(pmpfiles);
         //FileTool.NewFolder(pmpfiles);//新建一个文件夹
         var pdfConfig = new PlotterConfiguration(Path_pc3)
         {
             ModelPath = pmpfiles,
             DriverPath = drvFilePath,
             TruetypeAsText = true,
             //PlotToFile = true,
         };
         var names = new string[] { "media", "io", "res_color_mem", "custom" };
         foreach (var name in names)
         {
             pdfConfig.Remove(name);
         }
         //解压了打印机信息之后,遍历打印机节点  
         foreach (var nodeA in pdfConfig)
         {
             switch (nodeA.NodeName)
             {
                 case "meta":
                     nodeA.Values.Remove("config_description_str");
                     nodeA.Values.Remove("config_autospool");
                     break;
             }
         }
         string str =
             "{\nabilities=\"500005500500505555000005550000000550000500000500000\n" +
             "caps_state=\"000000000000000000000000000000000000000000000000000\n" +
             "ui_owner=\"11111111111111111111110\n" +
             "size_max_x=320000.00000\n" +
             "size_max_y=320000.00000\n}";
         pdfConfig.Add("mod", "").Add("media", str);
         pdfConfig.Add("del", "", true);
         pdfConfig.Add("udm", "", true).Add("media", str);
         pdfConfig.Add("hidden", "", true);
         Path_pmp = pmpfiles + "\\" + Dwgtopdf + ".pmp";
         pdfConfig.Saves(Path_pmp);
     }

     /// <summary>
     /// 附着pmp路径到pc3内
     /// </summary>     
     public void ChangUserDefinedModel()
     {
         //获取这个打印机的完整路径 
         var ns = new string[] { Path_pc3, Path_pmp };
         foreach (var path in ns)
         {
             if (!File.Exists(path))
             {
                 continue;
             }
             var PdfConfig = new PlotterConfiguration(path);
             //解压了打印机信息之后,遍历打印机节点
             foreach (var nodeA in PdfConfig)
             {
                 if (nodeA.NodeName == "meta")
                 {
                     nodeA.ValueChang("user_defined_model_pathname" + "_str", Path_pmp);
                     break;
                 }
             }
             //PdfConfig.Saves();
             PdfConfig.Saves(path);
         }
     }

     public void InitDict()
     {
         hdiDict.Add("DWG To PDF", "pdfplot");
         hdiDict.Add("DWF6 ePlot", "dwfplot");
         hdiDict.Add("PublishToWeb JPG", "raster");
         hdiDict.Add("PublishToWeb PNG", "raster");
     }

 }
public class Printer
{
    //节点名称-纸张中英兑换表
    public const string str_size = "size";
    //节点名称-纸张边界信息
    public const string str_description = "description";
    /// <summary>
    /// 打印纸张全球名
    /// </summary>
    public string Name { private set; get; }
    /// <summary>
    /// 打印纸张本地名(中文名)
    /// </summary>
    public string Localized_name
    {
        get
        {
            return Name.Replace("_", " ").Replace("MM", "毫米");
        }
    }
    /// <summary>
    /// 打印纸张英文名
    /// </summary>
    public string Media_description_name { private set; get; }
    private double Offset_Left = 0;  //默认偏移量
    private double Offset_Down = 0; //默认偏移量 
    private double Offset_Top = 0;
    private double Offset_Right = 0;
                                    //纸张大小
    private double PaperX = 0;
    private double PaperY = 0;
    PlotterConfiguration PdfConfig;
    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="ext">纸张范围</param>
    /// <param name="offset_Left">左偏移量</param>
    /// <param name="offset_Down">下偏移量</param>
    public Printer(Extents2d ext, double offset_Left = 0, double offset_Down = 0)
    {
        //纸张大小
        var ve2 = ext.MinPoint.GetVectorTo(ext.MaxPoint);
        PaperX = ve2.X;
        PaperY = ve2.Y;
        Offset_Left = offset_Left;
        Offset_Down = offset_Down;
    }
    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="ve2">纸张范围</param>
    /// <param name="offset_Left">偏移量</param>
    /// <param name="offset_Down">偏移量</param>
    public Printer(Vector2d ve2, double offset_Left = 0, double offset_Down = 0) : this(ve2.X, ve2.Y, offset_Left, offset_Down)
    { }
    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="paperx">纸张横向长度</param>
    /// <param name="papery">纸张纵向高度</param>
    /// <param name="offset_Left">偏移量</param>
    /// <param name="offset_Down">偏移量</param>
    public Printer(double paperx, double papery, double offset_Left = 0, double offset_Down = 0, double offset_Right = 0, double tffset_Top = 0)
    {
        //纸张大小
        PaperX = paperx;
        PaperY = papery;
        Offset_Left = offset_Left;
        Offset_Down = offset_Down;
        Offset_Top = tffset_Top;
        Offset_Right = offset_Right;
    }
    /// <summary>
    /// 根据范围带下生成纸张,返回纸张名称
    /// </summary>
    /// <param name="ext">打印范围</param>
    /// <param name="dwgtopdfpmp">打印机pmp纸张文件路径</param> 
    /// <returns></returns>
    public PlotterConfiguration AddPrinter(string dwgtopdfpmp,ref string paperName)
    {
        Name = $"JBS_PDF_({PaperY:#0.00}_x_{PaperX:#0.00}_MM)";
        paperName = Name.Clone() as string;
        // JoinBoxStandard 嘻嘻
        //                                                              (5,_17)这个是默认偏移量
        // media_description_name="ISO_A0_Portrait_841.00W_x_1189.00H_-_(5,_17)_x_(836,_1172)_=959805_MM 
        //实际打印面积(虽然因为偏移值是0,等于长乘宽就可以,但是为了日后我忘记这里怎么算的,还是求一下吧)
        double area = (PaperY - (Offset_Left * 2)) * (PaperX - (Offset_Down * 2));
        //如果没有小数点保留,可能cad闪退!
        StringBuilder description_name = new StringBuilder();
        description_name.Append($"JBS_PDF_Portrait_{PaperY:#0.00}W_x_{PaperX:#0.00}H");
        description_name.Append("_-_");
        description_name.Append($"({Offset_Left:#0.00},_{Offset_Down:#0.00})");//偏移量
        description_name.Append("_x_");
        description_name.Append($"({PaperY - Offset_Left:#0.00},_{PaperX - Offset_Down:#0.00})_");
        description_name.Append($"={area:#0.00}_MM");
        Media_description_name = description_name.ToString();
        PdfConfig = new PlotterConfiguration(dwgtopdfpmp)
        {
            TruetypeAsText = true
        };

        //解压了打印机信息之后,遍历打印机节点
        foreach (var nodeA in PdfConfig)
        {
            if (nodeA.NodeName != "udm")
                continue;

            if (nodeA.Count() == 0)//这个是根据pc3生成pmp使用
                continue;

            foreach (var nodeB in nodeA)
            {
                if (nodeB.NodeName != "media")
                    continue;

                PiaNode piaNode_size = null;
                PiaNode piaNode_description = null;
                //遍历是否有节点
                foreach (PiaNode nodeC in nodeB)
                {
                    string nden = nodeC.NodeName;
                    switch (nden)
                    {
                        case str_size:
                            piaNode_size = nodeC;
                            break;
                        case str_description:
                            piaNode_description = nodeC;
                            break;
                    }
                }
                //找不到就添加节点
                if (piaNode_size == null)
                    piaNode_size = nodeB.Add(str_size);
                if (piaNode_description == null)
                    piaNode_description = nodeB.Add(str_description);

                //在节点中添加/修改信息
                AddPaperEnAndCn(piaNode_size);
                AddPaperDescription(piaNode_description);
                break;
            }
            break;
        }

        PdfConfig.Saves(dwgtopdfpmp);
        return PdfConfig;
    }
    /// <summary>
    /// 添加pmp纸张-中英兑换表
    /// </summary>
    /// <param name="nodeC"></param>
    private void AddPaperEnAndCn(PiaNode nodeC)
    {
        //图纸数量+1就是新建一张图   
        var spl = '\n';
        int count = nodeC.Count();
        string name = count.ToString();
        string[] paper = new string[] {
        name+ "{",
        $"caps_type=2",             //1是系统的,2是用户的.这里严格,可不可以在打印纸看见就是这里了
        $"name=\"{Name}",
        $"localized_name=\"{Localized_name}",
        $"media_description_name=\"{Media_description_name}",
        $"media_group=15",          //4是系统的,15是用户的.
        "landscape_mode=TRUE\n}",   //false是系统的,true是用户的
    };
        string paperAll = string.Join(spl + " ", paper) + spl;
        PlusNode(nodeC, name, paperAll);
    }
    /// <summary>
    /// 判断是否已有同名节点,有就不加入
    /// </summary>
    /// <param name="node"></param>
    /// <param name="name"></param>
    /// <param name="paperAll"></param>
    private void PlusNode(PiaNode node, string name, string paperAll)
    {
        bool yiyou = true;
        foreach (var nodeItem in node)
        {
            foreach (var pair in nodeItem.Values)
            {
                if (pair.Key == "media_description_name_str" &&
                    pair.Value == Media_description_name)
                {
                    yiyou = false;
                    break;
                }
            }
            if (!yiyou)
                break;
        }
        if (yiyou)
            node.Add(name, paperAll);
    }
    /// <summary>
    /// 添加pmp纸张-信息
    /// </summary>
    /// <param name="nodeC"></param>
    private void AddPaperDescription(PiaNode nodeC)
    {
        var spl = '\n';
        int count = nodeC.Count();
        string name = count.ToString();
        string[] paper = new string[] {
        name + "{",
        $"caps_type=2",  //1是系统的,2是用户的.这里严格,可不可以在打印纸看见就是这里了
        $"name=\"{Media_description_name}",
        $"media_bounds_urx={ChangDouble(PaperX)}",
        $"media_bounds_ury={ChangDouble(PaperY)}",
        $"printable_bounds_llx={ChangDouble(Offset_Left)}",
        $"printable_bounds_lly={ChangDouble(Offset_Down)}",
        $"printable_bounds_urx={ChangDouble(PaperX - Offset_Right)}",
        $"printable_bounds_ury={ChangDouble(PaperY - Offset_Top)}",
        $"printable_area={ChangDouble((PaperX - 2*Offset_Left)*(PaperY - 2*Offset_Down))}",
        "dimensional=TRUE\n}",
    };
        string paperAll = string.Join(spl + " ", paper) + spl;
        PlusNode(nodeC, name, paperAll);
    }
    /// <summary>
    /// 保证数字在12位内
    /// </summary>
    /// <param name="dos"></param>
    /// <returns></returns>
    string ChangDouble(double dos)
    {
        var str = string.Format("{0:0.0#########}", dos);
        if (str.Length >= 12)
            str = str.Substring(0, 12);
        return str;
    }
}

做了少许修改,惊惊大佬的创建纸张只有左下角的页边距,我另外加了右上角的页边距

//plotStyle是打印机的样式 PDF DWF JPG PNG
CreatePMP createPMP = new CreatePMP(plotStyle);
createPMP.ChangUserDefinedModel();
pmpPath = createPMP.Path_pmp;
string paperName = "";
 double paperX = (Math.Abs(p1.X - p2.X) / (double)(mth1Model.PrintScale));
 double paperY = (Math.Abs(p1.Y - p2.Y) / (double)(mth1Model.PrintScale));
Printer printer = new Printer(paperX, paperY, 0, 0, 0, 0);
printer.AddPrinter(pmpPath, ref paperName);

如此便可进行添加自定义的纸张

AcadDocument acadDocument = doc.GetAcadDocument() as AcadDocument;
acadDocument.SetVariable("BACKGROUNDPLOT", 0);
acadDocument.ActiveLayout.ConfigName = deviceName;
acadDocument.ActiveLayout.StyleSheet = mth1Model.PrintType;
Extents2d ext = GetExtents2D(p1, p2);

object LowerLeft = new double[2];
object UpperRight = new double[2];
((double[])LowerLeft)[0] = ext.MinPoint.X;
((double[])LowerLeft)[1] = ext.MinPoint.Y;
((double[])UpperRight)[0] = ext.MaxPoint.X;
((double[])UpperRight)[1] = ext.MaxPoint.Y;

acadDocument.ActiveLayout.SetWindowToPlot(LowerLeft, UpperRight);
acadDocument.ActiveLayout.PlotType = AcPlotType.acWindow;

acadDocument.ActiveLayout.PlotWithLineweights = true;
acadDocument.ActiveLayout.PlotWithPlotStyles = true;
if (plotStyle == "PDF")
{
    if (mth1Model.IsLb)
    {
        if (mth1Model.LbSize >= 0)
        {
            acadDocument.ActiveLayout.SetCustomScale(1, mth1Model.PrintScale);
        }
        else
        {
            double ratioX = (ext.MaxPoint.X - ext.MinPoint.X) / (paperX + mth1Model.LbSize);
            double ratioY = (ext.MaxPoint.Y - ext.MinPoint.Y) / (paperY + mth1Model.LbSize);
            acadDocument.ActiveLayout.SetCustomScale(1, Math.Max(ratioX, ratioY));
        }

    }
    else
    {
        acadDocument.ActiveLayout.SetCustomScale(1, mth1Model.PrintScale);
    }
    acadDocument.ActiveLayout.UseStandardScale = false;
}

acadDocument.ActiveLayout.CenterPlot = true;
//acadDocument.ActiveLayout.StandardScale = AcPlotScale.acScaleToFit;
//acadDocument.ActiveLayout.UseStandardScale = true;
//

string[] strs = acadDocument.ActiveLayout.GetCanonicalMediaNames() as string[];

acadDocument.ActiveLayout.PlotRotation = 0;
acadDocument.ActiveLayout.CanonicalMediaName = paperName;
acadDocument.ActiveLayout.PaperUnits = AcPlotPaperUnits.acMillimeters;


//acadDocument.Plot.DisplayPlotPreview(AcPreviewMode.acPartialPreview);
acadDocument.Plot.QuietErrorMode = true;

string saveName = "";
switch (mth1Model.OutputType)
{
    case "PDF":
        saveName = path + "\\" + fileName + ".PDF";
        break;
    case "DWF":
        saveName = path + "\\" + fileName + ".DWF";
        break;
    case "JPG":
        saveName = path + "\\" + fileName + ".PDF";
        break;
    case "PNG":
        saveName = path + "\\" + fileName + ".PDF";
        break;
    default:
        break;
}
// We'll be plotting a single document
if (File.Exists(saveName))
{
    File.Delete(saveName);
}

bool isOk = acadDocument.Plot.PlotToFile(saveName);
if (isOk)
{
    System.Diagnostics.Process.Start(saveName);
}
if (plotStyle == "PNG")
{

}
else if (plotStyle == "JPG")
{

}

 

posted on 2024-04-27 15:48  HRDK  阅读(5)  评论(0编辑  收藏  举报