import pythoncom from win32com.client import Dispatch, gencache import os from PIL import Image, ImageDraw, ImageFont from collections import defaultdict def export_opened_to_raster(): """ Функция для экспорта открытых документов КОМПАС в JPG, DXF и PDF Возвращает строку с подробной статистикой выполнения """ result = [] stats = { 'total_docs': 0, 'processed_docs': 0, 'jpg_created': 0, 'dxf_created': 0, 'errors': 0, 'created_files': defaultdict(list), 'pdf_created': False, 'pdf_path': None } try: # Получаем API интерфейсов версии 5 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) save_param = None images = [] application.Visible = True first_doc_name = None stats['total_docs'] = application.Documents.Count result.append(f"Найдено документов: {stats['total_docs']}") result.append("Начинаем обработку...\n") # Собираем информацию о всех документах перед созданием PDF 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 first_doc_name is None: first_doc_name = ( doc_api7.LayoutSheets.ItemByNumber(1).Stamp.Text(2).Str ) if doc_type == k_constants.ksDocumentSpecification: doc_api5 = api5_api.SpcActiveDocument() if doc_api5 and save_param is None: rasterParJPG = doc_api5.RasterFormatParam() rasterParJPG.Init() rasterParJPG.colorBPP = 8 rasterParJPG.colorType = 3 rasterParJPG.extResolution = 96 rasterParJPG.format = 0 rasterParJPG.greyScale = False # Сохраняем информацию о документе docs_info.append({ 'doc_api5': doc_api5, '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)}") # Обрабатываем каждый документ для сохранения JPG и DXF for doc_info in docs_info: try: for ext in ["jpg", "dxf"]: path = f"{doc_info['doc_path']}{ext}/" filename = f"{doc_info['doc_name']}.{ext}" full_path = os.path.join(path, filename) if not os.path.exists(path): os.makedirs(path) stats['created_files'][f"{ext}_dirs"].append(path) if ext == "jpg": doc_info['doc_api5'].SaveAsToRasterFormat(full_path, rasterParJPG) stats['jpg_created'] += 1 stats['created_files']['jpg_files'].append(full_path) img = Image.open(full_path) images.append(img) if ext == "dxf": doc_info['doc_api5'].ksSaveToDXF(full_path) stats['dxf_created'] += 1 stats['created_files']['dxf_files'].append(full_path) except Exception as e: stats['errors'] += 1 result.append(f"[ОШИБКА] При сохранении {doc_info['doc_name']}: {str(e)}") # Если есть изображения, создаем PDF if images and docs_info: first_doc_path = docs_info[0]['doc_path'] pdf_path = f"{first_doc_path}pdf/" if not os.path.exists(pdf_path): os.makedirs(pdf_path) stats['created_files']['pdf_dirs'].append(pdf_path) pdf_filename = f"{first_doc_name}_pages.pdf" pdf_output_path = os.path.join(pdf_path, pdf_filename) # Создаем заглавную страницу try: font = ImageFont.truetype("arial.ttf", size=48) except IOError: font = ImageFont.load_default() title_image = Image.new("RGB", (images[0].width, 200), color="white") draw = ImageDraw.Draw(title_image) title_text = f"{first_doc_name}\nКоличество страниц: {len(images)}" draw.text((10, 50), title_text, fill="black", font=font, spacing=10) images.insert(0, title_image) # Сохраняем PDF images[0].save( pdf_output_path, "PDF", resolution=96.0, save_all=True, append_images=images[1:], ) stats['pdf_created'] = True stats['pdf_path'] = pdf_output_path stats['created_files']['pdf_files'].append(pdf_output_path) # Формируем итоговый отчёт result.append("\n=== РЕЗУЛЬТАТЫ ===") result.append(f"Обработано документов: {stats['processed_docs']}/{stats['total_docs']}") result.append(f"Создано JPG-файлов: {stats['jpg_created']}") 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)