(超级干货)python打印cad图纸
本帖最后由 Eks6666 于 2024-4-8 02:15 编辑有了python打印cad,从此告别插件!!哈哈哈
from pyautocad import Autocadimport win32com.client
import win32print
import pythoncom
#acad = Autocad(create_if_not_exists = True)
acad = win32com.client.Dispatch("AutoCAD.Application.23") # AutoCAD.Application.23为 ProgID
acaddoc = acad.ActiveDocument
acadmod = acaddoc.ModelSpace
layout = acaddoc.layouts.item('Model')
plot = acaddoc.Plot
_PRINTER = win32print.GetDefaultPrinter()
_HPRINTER = win32print.OpenPrinter(_PRINTER)
#_PrinterStatus = 'Warning'
def PrinterStyleSetting():
acaddoc.SetVariable('BACKGROUNDPLOT', 0) # 前台打印
layout.ConfigName = 'RICOH MP C2011' # 选择打印机
layout.StyleSheet = 'monochrome.ctb' # 选择打印样式
layout.PlotWithLineweights = False # 不打印线宽
layout.CanonicalMediaName = 'A3' # 图纸大小这里选择A3
layout.PlotRotation = 1 # 横向打印
layout.CenterPlot = True # 居中打印
layout.PlotWithPlotStyles = True # 依照样式打印
layout.PlotHidden = False # 隐藏图纸空间对象
print(layout.GetPlotStyleTableNames()[-1])
layout.PlotType = 4
'''
PlotType (enum类型):
acDisplay: 按显示的内容打印.
acExtents: 按当前选定空间范围内的所有内容打印.
acLimits: 打印当前空间范围内的所有内容.
acView: 打印由 ViewToPlot 属性命名的视图.
acWindow: 打印由 SetWindowToPlot 方法指定的窗口中的所有内容.******
acLayout: 打印位于指定纸张尺寸边缘的所有内容,原点从 0,0 坐标计算。
'''
DEFAULT_START_POSITION =(3,3)
DRAWING_SIZE = (598,422)
DRAWING_INTEND = 700
class BackPrint(object):
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = super(BackPrint, cls).__new__(cls)
return cls._instance
def __init__(self,PositionX,PositionY):
self.x = PositionX
self.y = PositionY
@staticmethod
def APoint(x,y):
"""坐标点转化为浮点数"""
# 需要两个点的坐标
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x,y))
def run(self,Scale = 1.0):
#self.PrinterStyleSetting()
po1 = self.APoint(self.x * Scale - 1, self.y * Scale)
po2 = self.APoint(self.x * Scale - 1 + DRAWING_SIZE, self.y * Scale + DRAWING_SIZE) # 左下点和右上点
layout.SetWindowToPlot(po1, po2)
PrinterStyleSetting()
plot.PlotToDevice()
class PrintTask:
def __init__(self,maxPrintPositionArray,startPosition=(DEFAULT_START_POSITION,DEFAULT_START_POSITION)):
self._PrinterStatus = 'Waiting'
self.maxPrintPositionArray = maxPrintPositionArray # 此处要进行数据验证
self.printBasePointArray = []
self.taskPoint = startPosition
self.PrintingTaskNumber = 0
def runtask(self,):
if not self.printBasePointArray:
self.printBasePointArray = self.generalPrintBasePointArray(self.maxPrintPositionArray)
for position in self.printBasePointArray:
#printBasePointArray形式 : [(,),(,),]
self.taskPoint = position
current_task = BackPrint(*position)
current_task.run()
self.PrintingTaskNumber = len(win32print.EnumJobs(_HPRINTER,0,-1,1))
#print('ing-> ',self.PrintingTaskNumber,'position',position)
while self.PrintingTaskNumber >= 5:
time.sleep(1)
self.PrintingTaskNumber = len(win32print.EnumJobs(_HPRINTER,0,-1,1))
time.sleep(1)
def ResumeTask(self,):
pass
def generalPrintBasePointArray(self,maxPrintPositionArray):
printBasePointArray = []
next_drawing_xORy_intend = DRAWING_INTEND
current_x = int((self.taskPoint - 4)/ DRAWING_INTEND)*DRAWING_INTEND + DEFAULT_START_POSITION
current_y = int((self.taskPoint - 4)/DRAWING_INTEND)*DRAWING_INTEND + DEFAULT_START_POSITION
#print(current_x,current_y)
for position in maxPrintPositionArray:
while current_x <= position + DEFAULT_START_POSITION:
printBasePointArray.append((current_x,current_y))
current_x += next_drawing_xORy_intend
current_x = DEFAULT_START_POSITION
current_y += next_drawing_xORy_intend
return printBasePointArray #printBasePointArray形式 : [(,),(,),]
def getTaskNumber(self,):
TaskNumber = self.PrintingTaskNumber
try:
TaskNumber = len(win32print.EnumJobs(_HPRINTER,0,-1,1))
return TaskNumber
except Exception as e:
return TaskNumber
if __name__ == '__main__':
task = PrintTask(,(6194,4))
task.runtask()
import win32com.client
import win32print
import pythoncom
class AutoCADPrint:
def __init__(self):
self.acad = None
self.acaddoc = None
self.layout = None
self.plot = None
self.hprinter = None
def connect_autocad(self):
"""连接到 AutoCAD 应用程序并获取相关对象"""
try:
self.acad = win32com.client.Dispatch("AutoCAD.Application.23")
self.acaddoc = self.acad.ActiveDocument
self.layout = self.acaddoc.layouts.item('Model')
self.plot = self.acaddoc.Plot
except Exception as e:
print(f"Error connecting to AutoCAD: {e}")
def connect_printer(self):
"""连接默认打印机"""
try:
self.hprinter = win32print.OpenPrinter(win32print.GetDefaultPrinter())
except Exception as e:
print(f"Error connecting to printer: {e}")
def set_printer_style(self):
"""设置打印机的打印样式等参数"""
try:
self.layout.ConfigName = 'RICOH MP C2011'
self.layout.StyleSheet = 'monochrome.ctb'
self.layout.CanonicalMediaName = 'A3'
self.layout.PlotRotation = 1
self.layout.CenterPlot = True
self.layout.PlotWithPlotStyles = True
self.layout.PlotHidden = False
self.layout.PlotType = 4
except Exception as e:
print(f"Error setting printer style: {e}")
def plot_to_device(self, x, y, scale=1.0):
"""将指定区域的图形打印到设备上"""
try:
po1 = self.acaddoc.Utility.Point(x * scale - 1, y * scale)
po2 = self.acaddoc.Utility.Point(x * scale - 1 + 598, y * scale + 422)# Assuming DRAWING_SIZE is (598, 422)
self.layout.SetWindowToPlot(po1, po2)
self.plot.PlotToDevice()
except Exception as e:
print(f"Error plotting: {e}")
def close_connections(self):
"""关闭连接,释放资源"""
if self.hprinter:
win32print.ClosePrinter(self.hprinter)
if self.acad:
self.acad.Quit()
def run_print_tasks(tasks):
"""执行打印任务"""
autocad_printer = AutoCADPrint()
autocad_printer.connect_autocad()
autocad_printer.connect_printer()
autocad_printer.set_printer_style()
for task in tasks:
autocad_printer.plot_to_device(*task)
autocad_printer.close_connections()
if __name__ == '__main__':
# 示例打印任务列表,格式为 (x坐标, y坐标)
tasks = [(6194, 4), (6194, 100), (10000, 10000)]
run_print_tasks(tasks)
楼主厉害,但是插件会更加方便些,有的插件可以识别图块为打印框,有的可以判断最大的矩形为打印框,有的可以自动判断纸张大小,楼主请继续加油! 666666牛叉~沙发占定~ 先抢占一个沙发,楼主的技术{:1_921:} 可实现多图打印到文件吗? 厉害,这下打印图纸又方便快速了一些 晕,这就厉害了哈
厉害厉害,能人辈出 厉害呀,学习一下代码 看了一下打印设置部分,我还是选择用插件