因个人能力有限,只找到了打开.dxf格式的库,暂时未找到打开.dwg的库,若有可以打开.dwg的库,麻烦告知~
因没学过python,代码可能有的不是那么简洁,希望能给别人提供一点帮助,顺便自己做一个记录,望大佬就当看个乐~
首先,先说下先要条件:
1、文件需要是.dxf格式的文件,AutoCAD软件可以把CAD图纸(.dwg)转换为.dxf格式文件,这里我用的是2007版本的。
2、所有图框的所用图层要一致,而且颜色要是图层的颜色,不能自己更换过。
3、图框的四条线是直线,且不能由两条线组成。
4、不得有其他线段的图层是图框所用图层,不得有多余线段。
解释:
第二点,因为采用的是识别图层+颜色的方式来读取图框的坐标,所以要求图框使用的图层是一个图层,而且颜色要是图层的颜色(ByLayer),可能有人不懂,举个栗子:你在图层特征管理器中把图框所用的图层换个颜色,应用确认后,若是图框颜色变成换了的颜色,就是对的,没变颜色的图框就是后面自己更改过颜色。我图框所用图层的是细实线。两种颜色看着是一样的,但是 dxf.color 的值却是不一样的。
正确的
dxf.color == 256

错误的
dxf.color == 4

第三点,一般我们机械制图的图框都是四条直线,外侧的四根线为图框,所以也不会有由两条线组成一条线的情况出现,在此说明一下。因为是采集的起始点和终止点的坐标,一条直线要是由两条直线组成的那坐标就不一样了。

程序需要用AutoCAD软件打开.dxf图纸时执行!!!
开始,经典的导入库:
import ezdxf
import win32com.client
import pythoncom
import numpy as np
import keyboard程序流程是:
①、打开获取.dxf格式中符合满足线型类型dxftype()=='LINE',线图层dxf.layer == '粗实线',线颜色dxf.color == 256,并把满足条件的汇聚成一个列表。
这里有个好处,就是图框的四个点的坐标是连续的,把列表按4切片,得到的就是图框的四个坐标的x和y的值,但我们只需要左下和右上的坐标就行了。
②、把所有左下和右上的坐标输出到一个列表中,按照左下的xy值进行重新排列,目的是从下到上,从左到右的方式将图框依次打印出来。
③、按照重新排列的顺序将图纸打印出来。
程序代码:
# -*- coding: utf-8 -*-
"""
YH 30 17:00:00 2023
"""
import ezdxf
import win32com.client
import pythoncom
import numpy as np
import keyboard
def tbr(x):#按4切片,输出每个4内的左下和右上的坐标到list_Y
global list_Y
list_Y=[]
a = int(len(x)/4)
for sun in range(0,a):
list_zong=[]
list_zx=[]
list_ys=[]
list_one=[]
list_two=[]
b = x[sun*4]
list_one.append(b[0])
list_two.append(b[1])
c = x[sun*4+1]
list_one.append(c[0])
list_two.append(c[1])
d = x[sun*4+2]
list_one.append(d[0])
list_two.append(d[1])
e = x[sun*4+3]
list_one.append(e[0])
list_two.append(e[1])
list_zx.append(min(list_one)-5)
list_zx.append(min(list_two)-5)
list_ys.append(max(list_one)+5)
list_ys.append(max(list_two)+5)
list_zong.append(list_zx)
list_zong.append(list_ys)
list_Y.append(list_zong)
def sort_key(x):
return x[0][::-1]
def scr():
global acaddoc
acad = win32com.client.Dispatch("AutoCAD.Application.17")
# AutoCAD.Application.17为 ProgID为2007版本的CAD
acaddoc = acad.ActiveDocument
acaddoc.Utility.Prompt("Hello AutoCAD\n")
acadmod = acaddoc.ModelSpace
print('当前处理文件的目录为:%s'%(acaddoc.path))
print('当前处理文件名:%s'%(acaddoc.name))
# 打开 DWG 文件
dwg = ezdxf.readfile(acaddoc.name)
# 获取图形模型
modelspace = dwg.modelspace()
list_1=[]
for entity in modelspace:
zb_array = np.zeros([1,2])
# 判断是否是线段
if entity.dxftype() == 'LINE':
# 提取线段的图层
if entity.dxf.layer == "细实线" :
#判断线段的颜色
if entity.dxf.color == 256:
#输出线段的终点坐标
end_point = entity.dxf.end
zb_array[0][0]=end_point[0]
zb_array[0][1]=end_point[1]
a=zb_array.tolist()
list_1.append(a[0])
def APoint(x, y):
"""坐标点转化为浮点数"""
# 需要两个点的坐标
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y))
layout = acaddoc.layouts.item('Model') # 来个layout对象
plot = acaddoc.Plot
acaddoc.SetVariable('BACKGROUNDPLOT', 0) # 前台打印
layout.StyleSheet = 'monochrome.ctb' # 选择打印样式
layout.PlotWithLineweights = True # 打印线宽
layout.ConfigName = 'Brother HL-2260D Printer.pc3' # 选择打印机\绘图仪,根据你的打印机\绘图仪
layout.PlotRotation = 1 # 横向打印 不是0就是1,根据打印机
layout.StandardScale = 0# 图纸打印比例
layout.CenterPlot = True # 居中打印
layout.PlotWithPlotStyles = True # 依照样式打印
layout.PlotHidden = False # 隐藏图纸空间对象
if np.mod((len(list_1)),4) ==0:
tbr(list_1)
list_Z=sorted(list_Y,key = sort_key)#先按照左下的y值进行排序,在按照左下的x值进行排序
for po in range(len(list_Z)):
layout.CanonicalMediaName = 'A4'
po1 = APoint(list_Z[po][0][0],list_Z[po][0][1])
po2 = APoint(list_Z[po][1][0],list_Z[po][1][1])
layout.SetWindowToPlot(po1, po2)#设置打印窗口的坐标
plot.PlotToDevice()
print('打印结束')
else:
print('数据错误')
print('处理完毕')
if __name__ == '__main__':
scr()最后,看着限制挺多的,其实如果说绘图时按照标准,专门做个图框所用的图层,这样绘完图保存一下(到.dxf格式)就可以直接批量打印,不是很节约时间么,也能更愉快的摸鱼了~
















