Simple Web-based Spreadsheet using SpreadScript
A sample application written in Python using
SpreadScript to present a form-based
interactive spreadsheet on the web.
import sys
sys.path.append('/home/tkm/lib/python')
import cgi
import spreadscript
import os
import string
import tempfile
import traceback
TEMPXLS = '/spread_temp.xls'
TEMPXS3 = '/spread_temp.xs3'
TEMPCSV = '/spread_temp.csv'
def sendHeader():
print 'Content-type: text/html'
print
def showGreyTrout():
print '''<table border="0" cellspacing="0" cellpadding="0" align="right">
<tr><td>
<font size="-1">Powered by
<a href="http://www.greytrout.com/spreadscript.html">SpreadScript</a> from
<a href="http://www.greytrout.com/">GreyTrout Software</a>.<br>
<div align="right">
<a href="http://www.greytrout.com/spread.html">spread.py</a></div>
</font></td></tr></table>'''
def createNewSheet(form, numRows, numCols, level):
print '<%s>Create a new spreadsheet</%s>' % (level, level)
print '''<form method="post" action="/cgi-bin/spread.sh">
<table border="0" cellspacing="0" cellpadding="5">
<tr>
<td>Number of rows: </td>
<td><input type="text" name="numRows" value="%s"></td></tr>''' % \
(numRows, )
print '''<tr>
<td>Number of columns: </td>
<td><input type="text" name="numCols" value="%s"></td></tr>''' % \
(numCols, )
print '''<tr><td><input type="submit" name="action" value="Create">
</td></tr></table>
</form>'''
def showNewSheet(form):
sendHeader()
print '''<html><title>Create a New Spreadsheet</title>
<body bgcolor="white">'''
showGreyTrout()
createNewSheet(form, 4, 3, 'h1')
print '</body></html>'
def showSheet(form):
sendHeader()
print '<html><title>Spreadsheet</title> <body bgcolor="white">'
showGreyTrout()
print 'NOTE: Use .. rather than : for ranges. For example, a1..a4.<br>'
print 'NOTE: Begin formulas with =. For example, =sum(a1..a4).<p>'
numRows = 0
numCols = 0
if form.has_key('numRows'):
numRows = int(form['numRows'].value)
if form.has_key('numCols'):
numCols = int(form['numCols'].value)
if numRows == 0 or numCols == 0:
print '<b>Error:</b> Invalid dimensions: row = %d, column = %d<p>' % \
(numRows, numCols)
else:
print '<h1>Spreadsheet</h1>'
spreadscript.init("/home/tkm/bin/SpreadScript-license.txt")
book = spreadscript.Workbook()
book.activate()
sheet = book.createSheet("Sample")
if form.has_key('action') and form['action'].value == 'Recalc':
makeSheet(form, numRows, numCols, sheet)
sheet.recalc()
showGrid(form, numRows, numCols, sheet)
try:
book.save('/tmp' + TEMPXLS, spreadscript.SS_EXCEL_95)
os.chmod('/tmp' + TEMPXLS, 0644)
except:
pass
try:
book.save('/tmp' + TEMPXS3, spreadscript.SS_NEXS_XS3)
os.chmod('/tmp' + TEMPXS3, 0644)
except:
pass
try:
dims = sheet.getDimensions()
dims.exportCSV('/tmp' + TEMPCSV)
os.chmod('/tmp' + TEMPCSV, 0644)
except:
pass
print '<hr>'
createNewSheet(form, numRows, numCols, 'h2')
print '<hr>'
showGreyTrout()
print '</body>'
print '</html>'
def getCellContents(form, r, c):
cell = spreadscript.rcToText(r, c)
contents = None
if form.has_key(cell):
contents = string.strip(form[cell].value)
return contents
def isNumber(s):
try:
float(s)
return 1 except:
return 0
def makeSheet(form, numRows, numCols, sheet):
for r in range(1, numRows + 1):
for c in range(1, numCols + 1):
contents = getCellContents(form, r, c)
if contents and contents[0] == '=': sheet.setFormula(r, c, contents)
elif contents and isNumber(contents): sheet.setNumber(r, c, float(contents))
elif contents: sheet.setText(r, c, contents)
def showGridCmdArea(showFormulas, showValues, showBoth):
print '''<table width="100%" cellspacing="0" cellpadding="3"><tr>
<td valign="middle"><input type="submit" name="action"
value="Recalc"></td><td valign="middle">'''
print '''<table align="right" border="0" cellspacing="0" cellpadding="0">
<tr><td>Show:
<input type="radio" name="showwhat" value="showformulas" '''
if showFormulas:
print 'checked'
print '> formulas '
print '<input type="radio" name="showwhat" value="showvalues" '
if showValues:
print 'checked'
print '> values '
print '<input type="radio" name="showwhat" value="showboth" '
if showBoth:
print 'checked'
print '> both'
print ''' Save as:
<a href="%s">Excel file</a>
<a href="%s">NExS XS3 file</a>
<a href="%s">CSV file</a>
</td></tr></table>''' % (TEMPXLS, TEMPXS3, TEMPCSV)
print '</td></tr></table>'
def showGrid(form, numRows, numCols, sheet):
showFormulas = 0
showValues = 0
showBoth = 0
if form.has_key('showwhat'):
if form['showwhat'].value == 'showformulas':
showFormulas = 1
elif form['showwhat'].value == 'showvalues':
showValues = 1
elif form['showwhat'].value == 'showboth':
showBoth = 1
else:
showBoth = 1
print '''<form method="post" action="/cgi-bin/spread.sh">
<input type="hidden" name="numRows" value="%d">
<input type="hidden" name="numCols" value="%d">''' % \
(numRows, numCols)
showGridCmdArea(showFormulas, showValues, showBoth)
print '''<table border="1" cellspacing="0" cellpadding="2">
<tr><td bgcolor="#CCCCCC"> </td>'''
for c in range(1, numCols + 1):
print '<td bgcolor="#CCCCCC" align="center">%s</td>' % \
spreadscript.rcToText(1, c)[:-1] print '</tr>'
for r in range(1, numRows + 1):
print '<tr><td bgcolor="#CCCCCC" align="center">%d:</td>' % (r, )
for c in range(1, numCols + 1):
print '<td>' ,
if showValues or showBoth:
print sheet.getText(r, c) + '<br>' ,
print '<input type=' ,
if showFormulas or showBoth:
print '"text" size="13" ' , else:
print '"hidden" ' , print 'name="%s" ' % (spreadscript.rcToText(r, c), ) ,
contents = getCellContents(form, r, c)
if contents:
print 'value="%s"></td>' % (contents, )
else:
print '></td>'
print '</tr>'
print '</table>'
showFormulas = showValues = showBoth = 0
showGridCmdArea(showFormulas, showValues, showBoth)
print '</form>'
if __name__ == '__main__':
sys.stderr = sys.stdout
try:
form = cgi.FieldStorage()
if form.has_key('action') and form['action'].value == 'Recalc' or \
form.has_key('action') and form['action'].value == 'Create':
showSheet(form)
else: showNewSheet(form)
except:
sendHeader()
print '<p><b>An exception occurred.</b>\n<pre>'
traceback.print_exc()
print '</pre>'