Table to Excel geoprocessing service

3893
3
12-19-2012 02:02 PM
DavidAglietti
New Contributor III
Hello,
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
   CSV.
"""
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 = [f.name 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 = cursor.next()
            while row:
                yield [getattr(row, col) for col in fieldnames]
                row = cursor.next()
            del row, cursor
        else:
            # 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")
        else:
            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 http://pypi.python.org/pypi/xlwt"""
    try:
        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")
        return
    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(".","_"))
    worksheet.set_panes_frozen(True)
    worksheet.set_horz_split_pos(1)
    worksheet.set_remove_splits(True)

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

    workbook.save(output)
    

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)
        arcpy.SetParameterAsText(2,output_file)
    elif format == "XLS":
        try:
            output_file = os.path.join(scratch_path,'lois_export.xls')
            export_to_xls(dataset_name, output_file)
            arcpy.SetParameterAsText(2,output_file)
        except:
            import traceback
            arcpy.AddError(traceback.format_exc())
    
    else:
        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) {
        alert(featureSet.features.length);
        alert(fileFormat);
        var params = { "Input_Feature_Set":featureSet, "Format":fileFormat };
        esri.show(loading);
        gp.submitJob(params, completeCallback , statusCallback,function(error){
            alert(error.message);
            esri.hide(loading);
        });
        
    });
    
    
}
function completeCallback(jobInfo){
    if(jobInfo.jobStatus !== "esriJobFailed"){
      
      gp.getResultData(jobInfo.jobId,"Output_File", downloadFile);
    }
}
function statusCallback(jobInfo) {
    var status = jobInfo.jobStatus;
    if(status === "esriJobFailed"){
      alert(status);
      esri.hide(loading);
    }
    else if (status === "esriJobSucceeded"){
      esri.hide(loading);
    }
}


Thanks,
David
0 Kudos
3 Replies
KevinHibma
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
DavidAglietti
New Contributor III
Hello,
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
JeffJacobson
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