Table to Excel geoprocessing service

12-19-2012 02:02 PM
New Contributor III
I downloaded the Table to Excel geoprocessing tool from ArcGIS Online and I would like to publish it as a geoprocessing service.  My question is, how would I need to modify the script to accept an ArcGIS Javascript API FeatureSet as the input?  I see that the input parameter for the script is currently set to TableView.  I've changed it to be a "Feature Set" and modified the python code slightly to create the file in the Server's scratch workspace.  Unfortunately, when I call the function, I get this strange error reported in the server log:

updateParameters Execution Error: Runtime error : 'NoneType' object has no attribute 'lower'

I am guessing that my python code does work correctly against the FeatureSet object.  Anyone have any ideas?

Here is my python code:

# -*- coding: utf-8 -*-
   This script will convert a table to an excel spreadsheet. If the third-party
   module xlwt is available, it will use that. Otherwise, it will fall back to
import os
import sys
import arcpy
ver = arcpy.GetInstallInfo()['Version']

def header_and_iterator(dataset_name):
    """Returns a list of column names and an iterator over the same columns"""

    data_description = arcpy.Describe(dataset_name)
    fieldnames = [ for f in data_description.fields if f.type not in ["Geometry", "Raster", "Blob"]]

    def iterator_for_feature():
        if ver == u'10.0':
            cursor = arcpy.SearchCursor(dataset_name)
            row =
            while row:
                yield [getattr(row, col) for col in fieldnames]
                row =
            del row, cursor
            # leverage faster da cusors at 10.1
            with arcpy.da.SearchCursor(dataset_name, fieldnames) as cursor:
                for row in cursor:
                    yield row

    return fieldnames, iterator_for_feature()

def export_to_csv(dataset, output):
    """Output the data to a CSV file"""
    import csv

    def _encode(x):
        if isinstance(x, unicode):
            return x.encode("utf-8")
            return str(x)

    def _encodeHeader(x):
        return _encode(x.replace(".","_"))

    out_writer = csv.writer(open(output, 'wb'))
    header, rows = header_and_iterator(dataset)
    out_writer.writerow(map(_encodeHeader, header))
    for row in rows:
        out_writer.writerow(map(_encode, row))
def export_to_xls(dataset, output):
    Attempt to output to an XLS file. If xmlwt is not available, fall back
    to CSV.

    XLWT can be downloaded from"""
        sys.path.append(os.path.join(os.path.dirname(__file__), 'xlwt-0.7.4'))
        import xlwt
    except ImportError:
        arcpy.AddError("failed to import xlwt module")
    header, rows = header_and_iterator(dataset)

    # Make spreadsheet
    workbook = xlwt.Workbook()
    worksheet = workbook.add_sheet(os.path.split(dataset)[1])

    #Set up header row, freeze panes
    header_style = xlwt.easyxf("font: bold on; align: horiz center")
    for index, colheader in enumerate(header):
        worksheet.write(0, index, colheader.replace(".","_"))

    # Write rows
    for rowidx, row in enumerate(rows):
        for colindex, col in enumerate(row):
            worksheet.write(rowidx+1, colindex, col)

if __name__ == "__main__":
    dataset_name = arcpy.GetParameterAsText(0)
    scratch_path = arcpy.env.scratchWorkspace
    format = arcpy.GetParameterAsText(1)
    if format == "CSV":
        output_file = os.path.join(scratch_path,'lois_export.csv')
        export_to_csv(dataset_name, output_file)
    elif format == "XLS":
            output_file = os.path.join(scratch_path,'lois_export.xls')
            export_to_xls(dataset_name, output_file)
            import traceback
        raise ValueError("Don't know how to export to %r" % format)

Here is the javascript code that I call the service with:
function extractData(oidString,fileFormat){
    var query = new esri.tasks.Query();
    var qt = new esri.tasks.QueryTask(localServerPath + "/LOISOracle/MapServer/0");
    query.returnGeometry = false;
    query.where = "ESRI_OID in (" + oidString + ")";
    query.outFields = ["POINTNAME"];
    qt.execute(query, function (featureSet) {
        var params = { "Input_Feature_Set":featureSet, "Format":fileFormat };;
        gp.submitJob(params, completeCallback , statusCallback,function(error){
function completeCallback(jobInfo){
    if(jobInfo.jobStatus !== "esriJobFailed"){
      gp.getResultData(jobInfo.jobId,"Output_File", downloadFile);
function statusCallback(jobInfo) {
    var status = jobInfo.jobStatus;
    if(status === "esriJobFailed"){
    else if (status === "esriJobSucceeded"){

0 Kudos
3 Replies
Esri Regular Contributor
I've actually been testing these tools a little bit internally here as we're considering their inclusion into the core product.
I haven't looked at your code as we should be able to do this without modifying the scripts.
(I've found one issue with providing a record set directly as input to the tool)

What version are you on? 10 or 10.1
Whats your entire workflow? Just something that takes a "table" and outputs an excel file?
If I can better understand your whole workflow I might be able to provide a workable solution.
0 Kudos
New Contributor III
I am using version 10.  I would like to export the selected features (from a FeatureLayer) from my Javascript API application and export their attributes to a csv file.  Seems like it should be real easy but their is something going wrong.  Thanks for your help.
0 Kudos
Regular Contributor
I don't think you need to use an ArcGIS Server GP Service to do this.  This could all be done from your web server with some server-side code to convert from the JSON representation of your Features to CSV.

Here's an example in JavaScript, but it could be done in any language.  Since you are excluding the geometry from your output it should not be very difficult.
0 Kudos