kompas_window/export_opened_to_raster.py

201 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)