201 lines
8.5 KiB
Python
201 lines
8.5 KiB
Python
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) |