ezdxf 打印dxf为pdf

替换所有文本样式中的字体为 gbcbig.shx

for style in doc.styles:

style.dxf.font = 'gbcbig.shx'

python 复制代码
import ezdxf  
from ezdxf.addons.drawing import RenderContext, Frontend  
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend  
from ezdxf.addons.drawing.config import Configuration, LineweightPolicy  
import matplotlib.pyplot as plt  
import tkinter as tk  
from tkinter import filedialog, simpledialog  
import os  
import subprocess  
import sys  
import time  
  
# 添加常量  
SHOW_TIMING = False  
  
def dxf_to_pdf(dxf_path, pdf_path):  
    """将DXF文件转换为PDF,并将所有字体替换为gbcbig.shx"""  
    # 读取 DXF 文件  
    doc = ezdxf.readfile(dxf_path)  
      
    # 替换所有文本样式中的字体为 gbcbig.shx  
    for style in doc.styles:  
        style.dxf.font = 'gbcbig.shx'  
      
    # 创建渲染配置 - 完整的线宽控制  
    config = Configuration(  
        lineweight_scaling=0.05,  # 缩放因子,值越小线条越细  
        min_lineweight=0.05,      # 最小线宽(单位:1/300英寸)  
        lineweight_policy=LineweightPolicy.ABSOLUTE  # 使用绝对线宽策略  
    )  
      
    # 创建渲染环境 - 设置固定DPI确保一致性  
    fig = plt.figure(dpi=300)  
    ax = fig.add_axes([0, 0, 1, 1])  
      
    # 创建后端渲染器  
    backend = MatplotlibBackend(ax)  
    backend.configure(config)  # 显式配置后端  
      
    context = RenderContext(doc)  
      
    # 传入配置到前端  
    frontend = Frontend(context, backend, config=config)  
      
    # 渲染图形  
    frontend.draw_layout(doc.modelspace())  
    backend.finalize()  
      
    # 保存为 PDF - 使用相同DPI  
    fig.savefig(pdf_path, format='pdf', bbox_inches='tight', dpi=300)  
    plt.close(fig)  
  
def open_file(filepath):  
    """跨平台打开文件"""  
    if sys.platform.startswith('darwin'):  # macOS  
        subprocess.call(['open', filepath])  
    elif sys.platform.startswith('win'):   # Windows  
        os.startfile(filepath)  
    elif sys.platform.startswith('linux'): # Linux  
        subprocess.call(['xdg-open', filepath])  
  
def is_valid_dxf(dxf_path):  
    """验证DXF文件是否有效"""  
    try:  
        doc = ezdxf.readfile(dxf_path)  
        return True  
    except Exception:  
        return False  
  
def convert_dwg_to_dxf(dwg_file_path):  
    """  
    使用ODA File Converter将DWG文件转换为DXF文件  
      
    Args:  
        dwg_file_path (str): DWG文件路径  
          
    Returns:  
        dict: 转换结果,包含状态和DXF文件路径或错误信息  
    """  
    start_time = time.time()  
    try:  
        # 检查DWG文件是否存在  
        if not os.path.exists(dwg_file_path):  
            return {  
                "status": "error",  
                "message": f"DWG文件不存在: {dwg_file_path}"  
            }  
  
        # 获取文件目录和文件名  
        dwg_dir = os.path.dirname(dwg_file_path)  
        dwg_filename = os.path.basename(dwg_file_path)  
        dxf_filename = dwg_filename.replace('.dwg', '.dxf')  
        dxf_file_path = dwg_file_path.replace('.dwg', '.dxf')  
        if dxf_file_path == dwg_file_path:  
            dxf_file_path = f"{dwg_file_path}.dxf"  
  
        # 创建输出目录(如果不存在)  
        output_dir = os.path.dirname(dxf_file_path)  
        os.makedirs(output_dir, exist_ok=True)  
  
        # 参数定义(按官方规范)  
        TEIGHA_PATH = "ODAFileConverter"  
        INPUT_FOLDER = dwg_dir  
        OUTPUT_FOLDER = output_dir  
        OUTVER = "ACAD2018"           # 输入版本(如原文件是 ACAD2018)  
        OUTFORMAT = "DXF"             # 输出格式:只能是 DXF / DWG / DXB  
        RECURSIVE = "0"  
        AUDIT = "1"  
        INPUTFILTER = "*.DWG"         # 只处理DWG文件  
  
        # 构建命令(注意顺序!)  
        cmd = [  
            TEIGHA_PATH,  
            INPUT_FOLDER,  
            OUTPUT_FOLDER,  
            OUTVER,           # 输入版本  
            OUTFORMAT,        # 输出格式 ← 必须是 DXF/DWG/DXB  
            RECURSIVE,  
            AUDIT,  
            INPUTFILTER  
        ]  
  
        print(f"执行命令: {' '.join(cmd)}")  
  
        # 执行转换命令  
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=120)  
  
        # 打印调试信息  
        print("ODA 输出:", result.stdout)  
        print("ODA 错误:", result.stderr)  
  
        if result.returncode == 0:  
            # 检查DXF文件是否生成  
            if os.path.exists(dxf_file_path):  
                # 验证DXF文件是否有效  
                if is_valid_dxf(dxf_file_path):  
                    response = {  
                        "status": "success",  
                        "message": f"DWG文件已成功转换为DXF: {dxf_file_path}",  
                        "dxf_path": dxf_file_path  
                    }  
                    if SHOW_TIMING:  
                        response["processing_time"] = time.time() - start_time  
                    return response  
                else:  
                    response = {  
                        "status": "error",  
                        "message": f"生成的DXF文件结构不完整或损坏: {dxf_file_path}"  
                    }  
                    if SHOW_TIMING:  
                        response["processing_time"] = time.time() - start_time  
                    return response  
            else:  
                response = {  
                    "status": "error",  
                    "message": f"转换完成但未生成DXF文件。请检查输出目录: {output_dir}"  
                }  
                if SHOW_TIMING:  
                        response["processing_time"] = time.time() - start_time  
                return response  
        else:  
            response = {  
                "status": "error",  
                "message": f"ODA转换失败: {result.stderr}"  
            }  
            if SHOW_TIMING:  
                response["processing_time"] = time.time() - start_time  
            return response  
  
    except subprocess.TimeoutExpired:  
        response = {  
            "status": "error",  
            "message": "转换超时"  
        }  
        if SHOW_TIMING:  
            response["processing_time"] = time.time() - start_time  
        return response  
    except FileNotFoundError:  
        response = {  
            "status": "error",  
            "message": "未找到ODAFileConverter命令,请确保ODA File Converter已正确安装并加入PATH"  
        }  
        if SHOW_TIMING:  
            response["processing_time"] = time.time() - start_time  
        return response  
    except Exception as e:  
        response = {  
            "status": "error",  
            "message": f"转换过程中发生错误: {str(e)}"  
        }  
        if SHOW_TIMING:  
            response["processing_time"] = time.time() - start_time  
        return response  
  
def convert_single_cad_file():  
    """转换单个CAD文件(DXF或DWG)为PDF"""  
    # 创建隐藏的根窗口  
    root = tk.Tk()  
    root.withdraw()  # 隐藏主窗口  
    root.attributes('-topmost', True)  # 确保对话框置顶显示  
      
    # 选择文件夹  
    folder_path = filedialog.askdirectory(  
        title="选择包含CAD文件的文件夹"  
    )  
      
    if not folder_path:  
        print("未选择文件夹,程序退出")  
        root.destroy()  
        return  
      
    # 输入搜索条件  
    search_criteria = simpledialog.askstring(  
        "输入搜索条件",  
        "请输入要查找的文件名关键词:"  
    )  
      
    if not search_criteria:  
        print("未输入搜索条件,程序退出")  
        root.destroy()  
        return  
      
    root.destroy()  
      
    # 查找匹配的文件  
    matched_files = []  
    for root_dir, dirs, files in os.walk(folder_path):  
        for file in files:  
            if file.lower().endswith(('.dxf', '.dwg')) and search_criteria in file:  
                full_path = os.path.join(root_dir, file)  
                matched_files.append(full_path)  
      
    if not matched_files:  
        print(f"未找到包含 '{search_criteria}' 的CAD文件")  
        return  
      
    # 优化文件选择逻辑:如果有同名的DXF文件,优先使用DXF文件  
    optimized_files = {}  
    for file_path in matched_files:  
        base_name = os.path.splitext(os.path.basename(file_path))[0]  
        ext = os.path.splitext(file_path)[1].lower()  
          
        if base_name not in optimized_files:  
            optimized_files[base_name] = file_path  
        else:  
            # 如果已经存在该文件名的条目,检查扩展名优先级  
            existing_ext = os.path.splitext(optimized_files[base_name])[1].lower()  
            # DXF优先级高于DWG  
            if ext == '.dxf' and existing_ext == '.dwg':  
                optimized_files[base_name] = file_path  
      
    # 转换为列表  
    final_files = list(optimized_files.values())  
      
    # 如果找到多个匹配文件,让用户选择  
    if len(final_files) > 1:  
        print(f"找到 {len(final_files)} 个匹配的文件:")  
        for i, file_path in enumerate(final_files, 1):  
            print(f"{i}. {os.path.basename(file_path)}")  
          
        try:  
            choice = int(input("请输入要转换的文件编号: "))  
            if 1 <= choice <= len(final_files):  
                selected_file = final_files[choice - 1]  
            else:  
                print("无效的选择,程序退出")  
                return  
        except ValueError:  
            print("输入无效,程序退出")  
            return  
    else:  
        selected_file = final_files[0]  
        print(f"找到文件: {os.path.basename(selected_file)}")  
      
    pdf_path = None  # 初始化pdf_path变量  
      
    try:  
        # 获取文件扩展名  
        file_ext = os.path.splitext(selected_file)[1].lower()  
          
        if file_ext == '.dxf':  
            # 直接处理DXF文件  
            pdf_path = os.path.splitext(selected_file)[0] + ".pdf"  
            print(f"正在转换: {os.path.basename(selected_file)}")  
            dxf_to_pdf(selected_file, pdf_path)  
            print(f"转换完成: {pdf_path}")  
              
        elif file_ext == '.dwg':  
            # 处理DWG文件:先转换为DXF,再转换为PDF  
            print(f"正在转换DWG文件: {os.path.basename(selected_file)}")  
            conversion_result = convert_dwg_to_dxf(selected_file)  
              
            if conversion_result["status"] == "success":  
                dxf_path = conversion_result["dxf_path"]  
                pdf_path = os.path.splitext(dxf_path)[0] + ".pdf"  
                print(f"正在生成PDF: {os.path.basename(pdf_path)}")  
                dxf_to_pdf(dxf_path, pdf_path)  
                print(f"转换完成: {pdf_path}")  
            else:  
                print(f"DWG转换失败: {conversion_result['message']}")  
                return  # 转换失败则不继续执行  
              
    except Exception as e:  
        print(f"转换失败 {selected_file}: {e}")  
        return  # 转换失败则不继续执行  
      
    # 如果转换成功且生成了PDF文件,则打开它  
    if pdf_path and os.path.exists(pdf_path):  
        try:  
            print(f"正在打开PDF文件: {os.path.basename(pdf_path)}")  
            open_file(pdf_path)  
        except Exception as e:  
            print(f"打开PDF文件失败: {e}")  
    else:  
        print("PDF文件未生成或不存在")  
  
# 运行查找并转换版本  
if __name__ == "__main__":  
    convert_single_cad_file()
相关推荐
小咖自动剪辑4 小时前
Base64与图片互转工具增强版:一键编码/解码,支持多格式
人工智能·pdf·word·媒体
开开心心_Every12 小时前
家常菜谱软件推荐:分类齐全无广告步骤详细
linux·运维·服务器·华为od·edge·pdf·华为云
开开心心就好12 小时前
键盘映射工具改键位,绿色版设置后重启生效
网络·windows·tcp/ip·pdf·计算机外设·电脑·excel
cuber膜拜12 小时前
Marp CLI快速入门
pdf·npm·markdown·ppt·marp
reasonsummer12 小时前
【办公类-53-09】20260131Python模仿制作2025学年第二学期校历(excel+pdf)
python·pdf
心语星光13 小时前
用python语言的pyautogui库实现伪批量将xdf文件打印为pdf文件
开发语言·python·pdf·自动化
iReachers13 小时前
PDF一机一码加密大师1.1.0更新至2026最新版, 强力加密PDF, 无需额外安装阅读器, 附CSDN下载地址
pdf
web打印社区1 天前
前端开发实现PDF打印需求:从基础方案到专业解决方案
前端·vue.js·react.js·electron·pdf
Kratzdisteln1 天前
【MCM】(x= (N_A),y=(N_G),z=(p))RGB=T*
pdf
Kratzdisteln1 天前
【1902】process_assignment_pdf()
大数据·人工智能·pdf