Search Knowledge Base by Keyword
Getting Started: Building an Extension
Creating a .NET Class Library
You can download Visual Studio Template (C#) and start working on a project right away or create your own project, step-by-step. Extension Template includes both base extension class and the config file.
Extension Template:
Extension Template Link: PagosExtensionTemplate.zip
To use Visual Studio Templates;
- Copy the template file to Visual Studio’s templates folder (default: \My Documents\Visual Studio Version\Templates\ProjectTemplates\Language\)
- Run Visual Studio
- On the File menu, click New, and then click Project.
- Select template name (eg. PagosExtensionTemplate) under Templates > Visual C#
Detailed information: https://msdn.microsoft.com/en-us/library/y3kkate1.aspx
Steps:
If you decided to use template please continue from 6th item.
- Prepare your Excel file and convert it via SpreadsheetWeb Wizard Add-in. As a result; you can use
- Download SpreadsheetWebIO.dll from here and add it to the Extension Library Project:
using SpreadsheetWebIO
- If you are using SpreadsheetWeb 4.6 or above version; add ISSWebExtension to add Application_Init method:
public interface ISSWebExtension : SpreadsheetWebIO.ISSWebExtension { string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb); string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb); string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb); string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_); - Define extension class which should implement the interface ISSWebExtension from SpreadsheetWebIO:
public class ExtensionExample : ISSWebExtension { ... } - Add all of event methods into extension class. Following code sample also includes stubs to compile code without errors:
public string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_) { var ret = ""; outputs_ = null; return ret; } - We are ready to start our own coding. Let’s say we have an application with 2 numeric inputs and want to calculate and write their sum value into a label:
public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = false; // we don't want to triggering whole calculation outputs_ = new Dictionary<string, Dictionary<string, string>>(); // we will have outputs //INPUTS string inp_0_0 = inputs_["PSWInput_0_0"]; string inp_0_1 = inputs_["PSWInput_0_1"]; //CALCULATION double result = Double.Parse(inp_0_0) + Double.Parse(inp_0_1); //OUTPUTS outputs_.Add("PSWTab_0.Label_2_8", new Dictionary<string, string> { { "text", result.ToString() } }); //KEEP INPUTS foreach (string current in inputs_.Keys) { outputs_.Add(current, new Dictionary<string, string> { { "value", inputs_[current] } }); } return ret; }Value_Changed method is used because we wanted to trigger extension as we enter input. We can also use Button_Clicked to get result as a result of button click or Tab_Changed if we want calculations while tab is changed.
- Compile project to create extension library .dll file.
- Prepare config file. Be sure set true for used methods. Config file is an XML file which is saved as .config file. Sample name: Extension.config
<?xml version="1.0" encoding="utf-8" ?> <ExtensionConfig> <Type>Extension</Type> <Namespace>Extension</Namespace> <Class>Extension</Class> <Before_Value_Changed>false</Before_Value_Changed> <Value_Changed>true</Value_Changed> <After_Value_Changed>false</After_Value_Changed> <Before_Button_Click>false</Before_Button_Click> <Button_Click>true</Button_Click> <After_Button_Click>false</After_Button_Click> <Before_Tab_Changed>false</Before_Tab_Changed> <Tab_Changed>true</Tab_Changed> <After_Tab_Changed>false</After_Tab_Changed> <Application_Init>false</Application_Init> <Debug>false</Debug> <DebugFile>Extension.dll</DebugFile> </ExtensionConfig>
- Last step is combine .dll and .config file into a .zip archive and upload it to SpreadsheetWeb server. You can add an extension onto a file from Edit Application Page.

Full sample code:
using System;
using System.Collections.Generic;
using SpreadsheetWebIO;
namespace ExtensionTemplate
{
public interface ISSWebExtension : SpreadsheetWebIO.ISSWebExtension
{
string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
}
public class Extension : ISSWebExtension
{
public string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
public string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
{
var ret = "";
executeSSWeb = true;
outputs_ = null;
return ret;
}
public string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
{
var ret = "";
executeSSWeb = true;
outputs_ = null;
return ret;
}
public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
{
var ret = "";
executeSSWeb = false; // we don't want to triggering whole calculation
outputs_ = new Dictionary<string, Dictionary<string, string>>(); // we will have outputs
//INPUTS
string inp_0_0 = inputs_["PSWInput_0_0"];
string inp_0_1 = inputs_["PSWInput_0_1"];
//CALCULATION
double result = Double.Parse(inp_0_0) + Double.Parse(inp_0_1);
//OUTPUTS
outputs_.Add("PSWTab_0.Label_2_8", new Dictionary<string, string> { { "text", result.ToString() } });
//KEEP INPUTS
foreach (string current in inputs_.Keys)
{
outputs_.Add(current, new Dictionary<string, string> { { "value", inputs_[current] } });
}
return ret;
}
public string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
{
var ret = "";
outputs_ = null;
return ret;
}
}
}