Getting Started: Building an Extension
You can download Visual Studio Template (C#) and start working on creating an extension right away or create your own project.
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 queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_); string Before_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_); string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> 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 queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Application_Init(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> 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 queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = false; // we don't want to triggering whole calculation outputs_ = new Dictionary>(); // 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 { { "text", result.ToString() } }); //KEEP INPUTS foreach (string current in inputs_.Keys) { outputs_.Add(current, new Dictionary { { "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
Extension Extension Extension false true false false true false false true false false false Extension.dll
-
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 queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_); string Before_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_); string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_); string Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb); string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_); } public class Extension : ISSWebExtension { public string After_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } public string Button_Click(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Tab_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = true; outputs_ = null; return ret; } public string Value_Changed(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_, out bool executeSSWeb) { var ret = ""; executeSSWeb = false; // we don't want to triggering whole calculation outputs_ = new Dictionary>(); // 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 { { "text", result.ToString() } }); //KEEP INPUTS foreach (string current in inputs_.Keys) { outputs_.Add(current, new Dictionary { { "value", inputs_[current] } }); } return ret; } public string Application_Init(string vjsClientId_, string sender_, Dictionary queryStrings_, ref Dictionary inputs_, out Dictionary> outputs_) { var ret = ""; outputs_ = null; return ret; } } }
