191 lines
7.8 KiB
Python
191 lines
7.8 KiB
Python
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) |