Select to view content in your preferred language

Physically open a file using Arcpy

3792
10
Jump to solution
10-18-2018 08:55 AM
Paul_Christensen
Frequent Contributor

I have a script that runs the "Tabulate Intersection" tool for me that is assigned to a toolbar button. It works wonderfully. 

This is the first script I have created so I apologize if it is not as clean as it can be! 

My last step in this map automation, is to open the excel file once it is created instead of me having to navigate all the way to its location in the file explorer just to open it. That takes away the simplicity of just clicking a button and having the desired output.

One option is to just have the saved destination in a folder on my desktop that way it is just two clicks and I am there. But I wanted to first see if there was a way in arcpy to actually open a document in its native program (Excel) for viewing.

import arcpy
import pythonaddins

class TabulateSoil(object):
    """Implementation for Tools_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        
        # Set current map document
        mxd = arcpy.mapping.MapDocument("CURRENT")
        
        # Remove existing "Soil_Tabulate" from TOC
        for df in arcpy.mapping.ListDataFrames(mxd):
            for tbl in arcpy.mapping.ListTableViews(mxd,"",df):
                if tbl.name == "Soil_Tabulate":
                    arcpy.mapping.RemoveTableView(df, tbl)
                    
        # Define parameters
        table = r'C:\Users\pchristensen\Documents\ARCGIS\Default.gdb\Soil_Tabulate'
        in_table = r'c:\users\pchristensen\Documents\ARCGIS\Default.gdb\Soil_Tabulate'
        out_xls = r'C:\Users\pchristensen\Documents\ARCGIS\scratch\Soiltab.xls'

        # Delete "table"
        arcpy.Delete_management(table)
        
        # Run Tabulate Intersection tool against selected parcel polygon
        arcpy.TabulateIntersection_analysis("Parcel Polygon","TMS","Soil Polys", r"C:\Users\pchristensen\Documents\ARCGIS\Default.gdb\Soil_Tabulate", "MUSYM")
        
        # Run Table to Excel
        arcpy.Delete_management(out_xls)
        arcpy.TableToExcel_conversion(in_table,out_xls)
        
        del table
        del in_table
        del out_xls
        del mxd
        pass
0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

This is really a Python question and not ArcPy.  There are lots of good suggestions on the web about opening a file using default file type associations in Windows.  I would start with os.startfile from 15.1. os — Miscellaneous operating system interfaces — Python 2.7.15 documentation 

View solution in original post

10 Replies
GeorgeHouck
Occasional Contributor

I am about to launch a field collection app and I wanted to control the QAQC of the entries. So I wanted a day by day reminder to edit the collectors. I made my selections and excel sheet, but wanted it to come in my inbox. My IT came up with this for me...

# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------
# 
# Created on: 2018-10-16 
# By: Joe Simmons
# Description:  Sample script to send an email with and MS Excel attachment.

# ---------------------------------------------------------------------------


##print ("Beginning Excel to Email")

## Send the mail
import smtplib, os.path as op, base64, mimetypes
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import  formatdate
from email import encoders


## Process: Excel To Email
server = "YOUR SERVER"
sent_from = "YOUR EMAIL"
sent_to = ["DISTRIBUTION LIST OR EMAIL"] # must be a list
subject = "Craig's Daily Edits"
text = 'Please see attached.'
path = ('C:/Users/jsimmons/Documents/Dump/')       # Change to point to your directory.
send_filename = 'test.xlsx'                        # The name of your file.           

## Use MIMEMultipart to build email
msg = MIMEMultipart()
msg['From'] = sent_from
msg['To'] = "THEIR EMAIL"
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = subject

## Add Message Text
message = MIMEBase('text', 'plain')
message.set_payload(text)
encoders.encode_base64(message)
msg.attach(message)


## Add attachment
fp = open(path + send_filename, 'rb')
attachment = MIMEBase('application','vnd.openxmlformats-officedocument.spreadsheetml.sheet')   #Use theis for .xlsx files
#attachment = MIMEBase('application','vnd.ms-excel')                                           #Use theis for .xls files
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header('Content-Disposition', 'attachment', filename=send_filename)
msg.attach(attachment)



server = smtplib.SMTP(server)
server.ehlo()
server.starttls()
server.sendmail(sent_from, sent_to, msg.as_string())
server.quit()


# Confirmation
print ("Your Report for QAQC has been emailed.")
Paul_Christensen
Frequent Contributor

That is neat. I will keep this in mind in case I need to email something! I am just getting into scripting and I get excited thinking of all the possibilities.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

This is really a Python question and not ArcPy.  There are lots of good suggestions on the web about opening a file using default file type associations in Windows.  I would start with os.startfile from 15.1. os — Miscellaneous operating system interfaces — Python 2.7.15 documentation 

GeorgeHouck
Occasional Contributor

I placed it inside my GDR_DailyRun.py script and it interfaces well. You do not need to write a separate OS script, and it gives the user physical file to open.

Hope it is helpful.

Paul_Christensen
Frequent Contributor

Thank you!

You're a life saver. I just didn't know what to search for.

Here is my 'final' script. Works like a charm.

import arcpy
import pythonaddins
import os

class TabulateSoil(object):
    """Implementation for Tools_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):

        print "Initializing..."
        
        # Set parameters
        mxd = arcpy.mapping.MapDocument("CURRENT")
        path = r'C:\Users\pchristensen\Documents\ARCGIS'
        table = path + '\Default.gdb\Soil_Tabulate'
        out_xls = path + '\scratch\Soiltab.xls'

        print "Removing previous tables..."
        
        # Remove existing "Soil_Tabulate" from TOC
        for df in arcpy.mapping.ListDataFrames(mxd):
            for tbl in arcpy.mapping.ListTableViews(mxd,"",df):
                if tbl.name == "Soil_Tabulate":
                    arcpy.mapping.RemoveTableView(df, tbl)
                    
        # Delete "table"
        arcpy.Delete_management(table)

        print "Tabulating..."
        
        # Run Tabulate Intersection tool against selected parcel polygon
        arcpy.TabulateIntersection_analysis("Parcel Polygon","TMS","Soil Polys", table, "MUSYM")

        print "Exporting..."
        
        # Run Table to Excel
        arcpy.Delete_management(out_xls)
        arcpy.TableToExcel_conversion(table,out_xls)

        print "Opening..."

        os.startfile(out_xls)

        del mxd
        del path
        del table
        del out_xls

        print "DONE!!"
        pass
0 Kudos
Paul_Christensen
Frequent Contributor

Now I am running into the issue where ArcMap will crash unexpectedly during the "Opening" phase of this. 

Not every time though. It seems to happen when I run it once, select another polygon, and then run it again. 

It runs 100% the first time, I close Excel, run it again, crash.

What is the best way to go about seeing where it is going wrong?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

If you are opening it from within ArcMap, which you said but it didn't stick, I would use 17.1. subprocess — Subprocess management — Python 2.7.15 documentation .

Paul_Christensen
Frequent Contributor

Thank you. I perused that documentation and it was just way over my head so I couldn't really form a solution there.

However, I was able to find another well documented work around. With some playing, I got it to work without crashing for now.

Work Around for os.startfile Crashing arcmap 

JoshuaBixby
MVP Esteemed Contributor

What about the following, does it work for you:

import subprocess

xls_file = # path to xls file
subprocess.call(["cmd", "/c", "start", "", xls_path])
0 Kudos