import pythoncom from win32com.client import Dispatch, gencache import os from collections import defaultdict def export_opened_to_raster(): """ Функция для экспорта открытых документов КОМПАС в DXF и PDF Возвращает строку с подробной статистикой выполнения """ result = [] stats = { 'total_docs': 0, 'processed_docs': 0, 'dxf_created': 0, 'errors': 0, 'created_files': defaultdict(list), 'pdf_created': False, 'pdf_path': None } try: # Инициализация API КОМПАС api5_module = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0) api5_api = api5_module.KompasObject( Dispatch("Kompas.Application.5")._oleobj_.QueryInterface( api5_module.KompasObject.CLSID, pythoncom.IID_IDispatch ) ) module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0) api = module.IKompasAPIObject( Dispatch("Kompas.Application.7")._oleobj_.QueryInterface( module.IKompasAPIObject.CLSID, pythoncom.IID_IDispatch ) ) k_constants = gencache.EnsureModule( "{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0 ).constants application = module.IApplication(api) application.Visible = True first_doc_name = None stats['total_docs'] = application.Documents.Count if stats['total_docs'] == 0: return "[ОШИБКА] В КОМПАС не открыто ни одного документа." result.append(f"Найдено документов: {stats['total_docs']}") result.append("Начинаем обработку...\n") # Сбор информации о документах docs_info = [] for i in range(application.Documents.Count): try: doc = application.Documents.Open(i) doc_type = doc.DocumentType if doc_type in [ k_constants.ksDocumentDrawing, k_constants.ksDocumentFragment, k_constants.ksDocumentSpecification, ]: doc.Active = True # Активируем документ doc_path = doc.Path doc_name = "-".join(doc.Name.split(".")[:-1]) stats['processed_docs'] += 1 doc_api5 = api5_api.ActiveDocument2D() doc_api7 = module.IKompasDocument(doc) if not docs_info: try: first_doc_name = ( doc_api7.LayoutSheets.ItemByNumber(1).Stamp.Text(2).Str ) except: first_doc_name = "combined_documents" docs_info.append({ 'doc_api5': doc_api5, 'doc_api7': doc_api7, 'doc_path': doc_path, 'doc_name': doc_name, 'doc_type': doc_type }) result.append(f"Документ #{stats['processed_docs']}: {doc_name}") except Exception as e: stats['errors'] += 1 result.append(f"[ОШИБКА] Документ #{i+1}: {str(e)}") # Экспорт в DXF for doc_info in docs_info: try: dxf_dir = os.path.join(doc_info['doc_path'], "dxf") if not os.path.exists(dxf_dir): os.makedirs(dxf_dir) stats['created_files']['dxf_dirs'].append(dxf_dir) dxf_path = os.path.join(dxf_dir, f"{doc_info['doc_name']}.dxf") doc_info['doc_api5'].ksSaveToDXF(dxf_path) stats['dxf_created'] += 1 stats['created_files']['dxf_files'].append(dxf_path) result.append(f"Создан DXF: {dxf_path}") except Exception as e: stats['errors'] += 1 result.append(f"[ОШИБКА] При сохранении DXF {doc_info['doc_name']}: {str(e)}") # Создание PDF if docs_info and first_doc_name: try: pdf_dir = os.path.join(docs_info[0]['doc_path'], "pdf") if not os.path.exists(pdf_dir): os.makedirs(pdf_dir) stats['created_files']['pdf_dirs'].append(pdf_dir) pdf_filename = f"{first_doc_name}_vector.pdf" pdf_output_path = os.path.join(pdf_dir, pdf_filename) # Сохраняем каждый документ в PDF temp_pdfs = [] for doc_info in docs_info: doc_pdf_path = os.path.join(pdf_dir, f"{doc_info['doc_name']}_temp.pdf") try: # Активируем документ перед сохранением doc_info['doc_api7'].Active = True # Попытка сохранить документ в PDF через SaveAs doc_info['doc_api7'].SaveAs(doc_pdf_path) temp_pdfs.append(doc_pdf_path) # Убираем сообщение о создании PDF # result.append(f"Создан PDF: {doc_pdf_path}") except Exception as e: # Если SaveAs не поддерживает PDF, используем альтернативный метод dxf_path = os.path.join(doc_info['doc_path'], "dxf", f"{doc_info['doc_name']}.dxf") convert_dxf_to_pdf(dxf_path, doc_pdf_path) temp_pdfs.append(doc_pdf_path) # Убираем сообщение о преобразовании DXF в PDF # result.append(f"Преобразован DXF в PDF: {doc_pdf_path}") # Объединяем все PDF в один файл merge_pdfs(temp_pdfs, pdf_output_path) # Удаляем временные PDF for temp_pdf in temp_pdfs: os.remove(temp_pdf) # Убираем сообщение об удалении временного PDF # result.append(f"Удален временный PDF: {temp_pdf}") stats['pdf_created'] = True stats['pdf_path'] = pdf_output_path stats['created_files']['pdf_files'].append(pdf_output_path) result.append(f"Создан векторный PDF: {pdf_output_path}") except Exception as e: stats['errors'] += 1 result.append(f"[ОШИБКА] При создании PDF: {str(e)}") # Формируем итоговый отчёт result.append("\n=== РЕЗУЛЬТАТЫ ===") result.append(f"Обработано документов: {stats['processed_docs']}/{stats['total_docs']}") result.append(f"Создано DXF-файлов: {stats['dxf_created']}") result.append(f"PDF создан: {'Да' if stats['pdf_created'] else 'Нет'}") result.append(f"Ошибок: {stats['errors']}\n") # if stats['pdf_created']: # result.append(f"PDF сохранён: {stats['pdf_path']}\n") # Выводим список созданных файлов # result.append("Созданные файлы и папки:") # for file_type, files in stats['created_files'].items(): # if files: # result.append(f"\n{file_type.replace('_', ' ').title()}:") # for f in files: # result.append(f" • {f}") except Exception as e: result.append(f"\n[КРИТИЧЕСКАЯ ОШИБКА] {str(e)}") return "\n".join(result) def merge_pdfs(paths, output_path): """Объединяет несколько PDF в один.""" from PyPDF2 import PdfMerger merger = PdfMerger() for path in paths: merger.append(path) merger.write(output_path) merger.close() def convert_dxf_to_pdf(dxf_path, pdf_path): """Преобразует DXF в PDF.""" from dxf2pdf import convert convert(dxf_path, pdf_path)