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()
相关推荐
~烈13 小时前
Acrobat Pro DC 便携精简版 PDF 专业处理工具安装教程
pdf·acrobat pro dc·pdf 专业处理工具
我不是QI14 小时前
Master PDF Editor 逆向复现
汇编·安全·pdf
蓝创工坊Blue Foundry15 小时前
多个同模板 PDF,怎样批量提取同一类字段到 Excel
运维·数据库·pdf·自动化·ocr·excel
asdzx672 天前
Python PDF 拆分实战指南:单页拆分与按需页码范围拆分
开发语言·python·pdf
慧都小妮子2 天前
Aspose.CAD for .NET 26.6 更新发布
pdf·.net·3d渲染·cad·pdf导出·ifc编辑
蝉蜕日记2 天前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
蓝创工坊Blue Foundry2 天前
PDF 批量提取指定内容到 Excel:按字段整理多个 PDF 的方法
pdf·ocr·excel·文心一言·paddlepaddle·paddle
Am-Chestnuts3 天前
AI长回答批量导出PDF与长图:多轮内容整理和免费Markdown备份
人工智能·pdf·aigc
zyplayer-doc3 天前
研发接口文档怎么长期维护:zyplayer-doc把API、Markdown和变更记录放进同一个知识库
大数据·数据库·人工智能·笔记·pdf·ocr
蜡台3 天前
uniapp pdf文件预览组件
pdf·uni-app·合同·pdfh5