CAD插件实现块属性值与excel的互动,效果如下:
加载dll插件(CAD 命令行输入netload ,运行xx即可导出Excel,运行xx1即可根据excel更新dwg块属性值。)
部分代码如下
// 4. 开启事务更新CAD数据
using (Transaction trans = doc.Database.TransactionManager.StartTransaction())
{
try
{
int updatedCount = 0; // 记录更新成功的块数
// 5. 获取模型空间中的块参照(与导出时逻辑一致)
BlockTableRecord modelSpace = trans.GetObject(
doc.Database.CurrentSpaceId,
OpenMode.ForRead) as BlockTableRecord;
// 6. 遍历CAD中的块参照(按X坐标排序,与导出顺序一致)
var cadBlocks = modelSpace
.Cast<ObjectId>()
.Where(objId => objId.ObjectClass.Name == "AcDbBlockReference")
.Select(objId => trans.GetObject(objId, OpenMode.ForRead) as BlockReference)
.Where(blockRef => blockRef != null)
.OrderBy(b => b.Position.X) // 与导出排序一致,确保序号对应
.ToList();
// 7. 匹配Excel数据与CAD块参照(按序号匹配)
for (int i = 0; i < excelData.Count; i++)
{
ExcelBlockData excelBlock = excelData[i];
if (i >= cadBlocks.Count) break; // Excel行数超过CAD块数时终止
BlockReference cadBlock = cadBlocks[i];
if (cadBlock == null) continue;
// 8. 以写模式重新打开块参照(关键!否则无法修改属性)
cadBlock = trans.GetObject(cadBlock.ObjectId, OpenMode.ForWrite) as BlockReference;
if (cadBlock == null) continue;
// 9. 获取块参照的属性字典(标签名 -> 属性对象)
Dictionary<string, AttributeReference> cadAttrDict = GetBlockAttributes(cadBlock, trans);
// 10. 遍历目标属性,更新不一致的值
foreach (var kvp in excelBlock.AttributeValues)
{
string tag = kvp.Key;
string excelValue = kvp.Value;
// 检查CAD中是否存在该属性
if (cadAttrDict.TryGetValue(tag, out AttributeReference cadAttr))
{
// 以写模式重新打开属性(关键!否则无法修改值)
cadAttr = trans.GetObject(cadAttr.ObjectId, OpenMode.ForWrite) as AttributeReference;
if (cadAttr == null) continue;
// 比较值(忽略空值或未修改的情况)
if (!string.IsNullOrEmpty(excelValue) && cadAttr.TextString != excelValue)
{
cadAttr.TextString = excelValue; // 更新属性值
updatedCount++;
}
}
}
}
trans.Commit(); // 提交事务
ed.WriteMessage($"\n成功更新 {updatedCount} 个属性值!");
}
catch (Exception ex)
{
trans.Abort();
ed.WriteMessage($"\n更新失败: {ex.Message}");
}
}
插件联系↓↓↓