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; } } }