要实现批量打印,那么我们画图时图纸就必须规范统一。因为python优势是执行重复性工作,尽量不让python去做判断。
- 每张图纸一个CAD文件
- 所有图纸用统一的图框,例如A1
- 所有图纸的图框左下角起始位置均一样,例如我们全选所有图形,尽量Move移动到原点坐标那,那么图框左下角位置就是(0,0)了。如果没有办法设置左下角统一位置,那么,有2个办法,一个通过python获取到图纸图元最左下角坐标是多少,这个有点慢还有可能不准,这个不讲了,自己问问AI。另一个方法,就是手动点击获取坐标值,这个比较准确,但是不是全自动生产图纸了,需要人工干预了,一会再讲。所以为了方便,在做图时尽量统一坐标。
另外,世界坐标和用户坐标的问题,打印时用的是世界坐标,所以需要把用户坐标与世界坐标重合,一般情况默认是重合的,如果你的用户坐标变了,那么需要你重新移动回去,AutoCAD命令行(ctrl+9可以启动命令行)输入usc,选择世界w即可让用户坐标系与世界坐标系重合。
规范统一了,就可以批量打印了。我们选择打印范围是窗口时,直接给它一个坐标就行,起始坐标是(0,0),结束坐标就是图纸尺寸了,例如ISOA1(841.00x594.00MM),那结束坐标就是(841,594)
我使用的环境如下:
Python:3.11
操作系统:Windows 11
CAD软件:AutoCAD 2024
Python IDE:Jupyter lab
首先,我们测试一个cad文件。
第一步需要python连接CAD,我们也不用别的库,直接通过win32com,简单暴力!
import win32com.client
# 连接到 AutoCAD 应用程序
acad = win32com.client.Dispatch("AutoCAD.Application")
acad.Visible = True # 显示 AutoCAD窗口,不想显示True改为False
# 打开指定的DWG文件,建议使用全路径,例如F:\python\CAD2PDF\test.dwg,虽然jupyter可以不使用全路径,仅仅test.dwg就可以,但是容易报错。
acaddoc = acad.Documents.Open(r"改为你的CAD路径/test.dwg”)
# 获取模型空间
acadmod = acaddoc.ModelSpace
layout = acaddoc.layouts.item('Model') # 连接layout对象“模型”
#打印一下,看看是否正确
print('当前处理文件的目录为:%s'%(acaddoc.path))
print('当前处理文件名:%s'%(acaddoc.name))
第二步就要设置打印机了。
plot = acaddoc.Plot
acaddoc.SetVariable('BACKGROUNDPLOT', 0) # 前台打印
当我们使用AutoCAD打印时,我们需要设置以下几项
如,打印机名称,图纸尺寸,打印范围,是否居中打印,是否要不满图纸,打印样式,单位,图纸方向等。
那么,用python打印是一样的,只是通过python告诉AutoCAD而已。
我们首先通过python获取到这些配置。
- 打印机名称有哪些?
print(layout.GetPlotDeviceNames ())
打印PDF的话,我们使用'DWG To PDF.pc3'
layout.ConfigName = 'DWG To PDF.pc3' # 选择打印机
提示,如果你的python报错,重新连接以下CAD。
-
看看有哪些图纸尺寸可选
print(layout.GetCanonicalMediaNames() )
在此,我们选择'ISOA1(594.00x841.00MM)'
layout.CanonicalMediaName = 'ISOA1(841.00x594.00MM)'
-
参看有哪些打印样式
print(layout.GetPlotStyleTableNames() )
一般出图时不显示彩色线条,我们选择'monochrome.ctb'
layout.StyleSheet = 'monochrome.ctb'
- 其他打印设置
layout.PlotWithLineweights = True # 打印线宽
layout.PlotRotation = 0 # 横向打印
layout.StandardScale = 0# 图纸打印比例
layout.CenterPlot = True # 居中打印
layout.PlotWithPlotStyles = True # 依照样式打印
layout.PlotHidden = False # 隐藏图纸空间对象
layout.PaperUnits = 1 #设置单位为mm
- 设置打印范围为窗口
layout.PlotType = 4#设置安装坐标窗口打印,若无此行,按照窗口显示的打印。
设置完之后,就需要给它一个坐标值了。
坐标值不能直接给,需要转换一下,至于为什么,我也不知道。。。。
import pythoncom
def APoint(x, y):
"""坐标点转化为浮点数"""
# 需要两个点的坐标
return win32com.client.VARIANT(pythoncom.VTARRAY | pythoncom.VTR8, (x, y))
start = APoint(0,0)
finish = APoint(841,594)#A1图纸,其他图纸根据情况修改
转换完之后就可以直接给它了。
layout.SetWindowToPlot(start, finish)#设置打印窗口的坐标
- 打印成pdf
plot.PlotToFile(acaddoc.path +'/' + acaddoc.name[:-4] + ".pdf")
acaddoc.path文件所在的路径,acaddoc.name[:-4]文件名(不取后四位就是不取.dwg),最后生成了一个pdf文件,并保存到了原来CAD文件夹里,而且名字也和cad文件一样。
- 关闭文件
acaddoc.Close()
至此,一个cad文件打印成PDF就完成了。
如果需要批量打印,那么我们就遍历一下文件夹就行。并且把以上代码放到一个自定义函数里就可以了,不在啰嗦了。。。。参考如下:
import win32com.client
import pythoncom
import time,os
def APoint(x, y):
"""坐标点转化为浮点数"""
# 需要两个点的坐标
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y))
def topdf(dwg_file):
# 连接到 AutoCAD 应用程序
acad = win32com.client.Dispatch("AutoCAD.Application")
acad.Visible = True # 显示 AutoCAD窗口,不想显示True改为False
# 打开指定的DWG文件
acaddoc = acad.Documents.Open(dwg_file)
time.sleep(2)#根据自身电脑打开cad文件的时间选择
# 获取模型空间
acadmod = acaddoc.ModelSpace
layout = acaddoc.layouts.item('Model') # 连接layout对象“模型”
#打印一下,看看是否正确
print('当前处理文件的目录为:%s'%(acaddoc.path))
print('当前处理文件名:%s'%(acaddoc.name))
plot = acaddoc.Plot
acaddoc.SetVariable('BACKGROUNDPLOT', 0) # 前台打印
layout.ConfigName = 'DWG To PDF.pc3' # 选择打印机
layout.CanonicalMediaName = 'ISO_A1_(841.00_x_594.00_MM)' #图纸尺寸
layout.StyleSheet = 'monochrome.ctb'#打印样式
layout.PlotWithLineweights = True # 打印线宽
layout.PlotRotation = 0 # 横向打印
layout.StandardScale = 0# 图纸打印比例
layout.CenterPlot = True # 居中打印
layout.PlotWithPlotStyles = True # 依照样式打印
layout.PlotHidden = False # 隐藏图纸空间对象
#layout.PaperUnits = 1 #设置单位为mm
layout.PlotType = 4#设置安装坐标窗口打印,若无此行,按照窗口显示的打印
start = APoint(0,0)
finish = APoint(857.57,603)#A1图纸,其他图纸根据情况修改
layout.SetWindowToPlot(start, finish)#设置打印窗口的坐标
plot.PlotToFile(acaddoc.path +'/' + acaddoc.name[:-4] + ".pdf")
acaddoc.Close()
file_path = r"你dwg文件所在路径"
dwg_file = os.listdir(file_path)
for i in dwg_file:
if '.dwg' in i:
topdf(os.path.join(file_path,i))
最后再说一下起始点的设置,如果你已经画完图了,用户左边你也移动过了,并且移动图到原点很麻烦,那么我们就弄个半自动出图,就是当需要输入左下角坐标时(也就是之前的0,0坐标点),我们调处需要手动获取坐标点。
pointstart = acaddoc.Utility.GetPoint()#通过鼠标点击获取坐标
start = APoint(pointstart[0],pointstart[1])
finish = APoint(pointstart[0]+pointstart[1]+ 841, 594)#A1图纸,其他图纸根据情况修改