RSS
 

Archive for September, 2016

Interacting with photoshop, microsoft word and other apps from python via COM API

10 Sep

So i have been working on a python application that must talk to Solid Edge

Solid Edge is a 2d/3d CAD software from Siemens used to create drawings for engineering parts, etc
My job is to modify an existing excel file, launch solid edge’s .par and .dft files, update .dft based on .par,
save both and export both to PDFs.

Looked pretty straightforward, hmm?
This wasn’t, at least for me, so i will try to document how i got this working.

there you go!

import win32com.client,  os, xlsxwriter, struct, pywintypes, sys

from PyQt4 import QtCore, QtGui

def fix_com_exception(e):
    e.hresult = fix_com_hresult(e.hresult)
    e.args = [e.hresult] + list(e.args[1:])
    return e

def fix_com_hresult(hr):
    return struct.unpack("L", struct.pack("l", hr))[0]

def alert(e="Unknown error!"):
    app = QtGui.QApplication(sys.argv)
    QtGui.QMessageBox.warning(QtGui.QWidget(),"Error!", repr(e))
    sys.exit(app.exec_())

class Drawer:
    def __init__(self):
        print "starting drawing module"

    def modifyExcelFile(self):
        print "modifying excel"

        try:
            # Create or overwrite Excel file and add a worksheet.
            workbook = xlsxwriter.Workbook('Excel_Linked_File.xlsx')
            worksheet = workbook.add_worksheet()

            # expand 1st column
            worksheet.set_column('A:A', 20)

            # make first row bold
            bold = workbook.add_format({'bold': True})
            worksheet.write('A1', 'Linked Excel file to a Solid Edge file for a hub.',bold)
            #add description text
            worksheet.write('A3', 'Outer Diameter')
            worksheet.write('A4', 'Wall Thickness')
            worksheet.write('A5', 'Inner Diameter')
            worksheet.write('A6', 'Hole Size')
            worksheet.write('A7', 'Number of Holes')
            worksheet.write('A8', 'Flange Diameter')
            worksheet.write('A9', 'Flange Thickness')
            worksheet.write('A10', 'Height')
            worksheet.write('A11', 'Pitch Circle Diameter')
            #add values
            worksheet.write('B3', 100)
            worksheet.write('B4', 15)
            worksheet.write('B5', 60)
            worksheet.write('B6', 16)
            worksheet.write('B7', 4)
            worksheet.write('B8', 200)
            worksheet.write('B9', 10)
            worksheet.write('B10', 120)
            worksheet.write('B11', 160)

            worksheet.write('B14', 150)

            #add units
            worksheet.write('C3', 'mm')
            worksheet.write('C4', 'mm')
            worksheet.write('C5', 'mm')
            worksheet.write('C6', 'mm')
            worksheet.write('C8', 'mm')
            worksheet.write('C9', 'mm')
            worksheet.write('C10', 'mm')
            worksheet.write('C11', 'mm')
            #write to disk
            workbook.close()

            print "Excel created successfully!"
        except IOError as e:
            print repr(e)
            alert(e)
        except:
            print "unknown error"
            alert()



    def openSolidEdge(self):
        #get date so we know when this got generated
        gen_date=QtCore.QDateTime.currentDateTime().toString("yyyy-MM-dd_hh_mm_ss")
        #launch solid

        print "launching solid edge"
        try:
            se = win32com.client.Dispatch("SolidEdge.Application")
            se.Visible=False #when set to false, exported pdfs doesn't show measurements
            se.DisplayAlerts=False

            print "opening part document"
            objDocuments = se.Documents
            objPart = objDocuments.Open(os.getcwd()+"\Hub.par", "SolidEdge.PartDocument")
            objPart.SaveAs(os.getcwd()+"\Hub_"+gen_date+".par.pdf", )
            objPart.Close(SaveChanges=1)

            print "opening draft document"
            objDraft = objDocuments.Open(os.getcwd()+"\Hub.dft", "SolidEdge.DraftDocument")
            for doc in objDraft.ActiveSheet.DrawingViews:
                doc.Update()
            objDraft.SaveAs(os.getcwd()+"\Hub_"+gen_date+".dft.pdf")
            objDraft.Close(SaveChanges=1)
        except pywintypes.com_error as e:
            fix_com_exception(e)
            print repr(e)
            alert(e)
        except:
            print "unknown error"
            alert()


        print "done! opening pdfs..."
        #uncomment next line to kill application after each usage, may be a bad idea if you process files often
        #se.Application.Quit()

        try:
            os.startfile(os.getcwd()+"\Hub_"+gen_date+".par.pdf")
            os.startfile(os.getcwd()+"\Hub_"+gen_date+".dft.pdf")
        except WindowsError as e:
            alert(e)
        except:
            print "unknown error"
            alert()



drawn=Drawer()
drawn.modifyExcelFile()
drawn.openSolidEdge()



Dont let this beat you, you can apply same to Photoshop, microsoft excel and other softwares with COM APIs