在实际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")
{
}
标签:name,自定义,double,description,acadDocument,Offset,二次开发,CAD,string From: https://www.cnblogs.com/HRDK-CADeveloper/p/18162147