416.467.9100 | Dundas Data Visualization | Login
Welcome Guest
This is the support page for the legacy Dundas Dashboard application. For assistance with the current Dundas BI application please click here.
Dashboard v5.0

This site makes extensive use of JavaScript.

Please enable JavaScript in your web browser and reload the page before proceeding.

Data and Image Export

Hide navigation
RSS
Modified on Tue, 22 Apr 2014 10:59 AM Categorized as Add-ons, Export, Samples

Overview

Although &dw; comes with CSV and PNG export functionality, as well as other export plug-ins (such as Excel Export and PDF Export) that can be downloaded, there are times when you need to export to a data or image format that is very specific to your organization.

This article will be a guide on how to create an html data export plug-in and a jpeg image export plugin.

Aside from the main html export plug-in itself, this article will also show how to use &dw; specific user interface elements (such as color picker) to create an options dialog that will allow you pass additional parameters to the main plug-in.

Requirements


Getting Started

This article shows how to create both a data export plug-in and an image export plug-in as two separate plug-in projects included in the sample solution.

Both are created as Silverlight class libraries using Silverlight Version 4 framework in a single Visual Studio 2010 solution.

Creating the Html Export plug-in project

  1. Add a new Silverlight Class Library project for the HtmlExport plug-in (to the main Solution)
    Create a new Silverlight Class Library project

    Create a new Silverlight Class Library project

  2. When asked to select Silverlight Version, select Silverlight 4
    Silverlight 4 target

    Silverlight 4 target

  3. Add references to the Dundas.Dashboard.Client.dll and Dundas.Dashboard.Plugins.dll assemblies (commonly found in C:\Program Files\Dundas Data Visualization Inc\&dw;\2.0.0\SDK\lib\Client\).

Creating the Jpeg Export plug-in project

The Jpeg Export plug-in project is created in much the same way as the Html Export plug-in project created above. The only needed references required however are Dundas.Dashboard.Client.dll and ImageTools.dll (commonly found in C:\Program Files\Dundas Data Visualization Inc\&dw;\2.0.0\SDK\lib\Client\).

In addition to the standard &dw; Client API assemblies, the project also requires the ImageTools.IO.Jpeg.dll assembly that is part of the ImageTools for Silverlight library.

Project Structures

Below is the general project structure of the two export projects involved in the sample solution.

General structure of the projects in the sample solution

General structure of the projects in the sample solution


Basics of an export class

The main class implements the IDashboardExport interface from the Client API library.

Below are the list of methods and properties that need to be implemented as part of the interface.

Using Dundas Dashboard controls

Besides the code required to export the data, the Html Export plug-in also makes use of &dw; controls to create an Advanced options screen.

To understand how to use &dw; controls and to create UI screens, refer to the files in the _wizard folder in the Html Export project.

The wizard is created using a standard View-Model pattern with the controls used in the XAML as shown below:

  

The wizard code also shows how to use the color picker control that is part of the Dundas Controls client library.

Html Export Advanced Options with &dw; controls

Html Export Advanced Options with &dw; controls


Methods


Properties




Sample Html Export output

Sample output produced by Html Export

Sample output produced by Html Export


Packaging and Installing &dw; Plug-ins

The HtmlExport project's output (HtmlExport.dll) and the JpegExport project's output (JpegExport.dll) must be packaged as a DataExport plug-in.

Because the JpegExport plug-in also uses an additional library (ImageTools.IO.Jpeg.dll) not included with &dw;, it too must be included as part of the packaging.

Refer to the References section for information on how to package and install plug-ins.

Once the plug-in is packaged and installed, in order for &dw; to load them, you must perform an iisreset.

Packaging of Jpeg Export plug-in

Packaging of Jpeg Export plug-in


References


Code

Simplified Data Export code
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Dundas.Dashboard.Extensibility;
using Dundas.Dashboard.Business;
using Dundas.Dashboard.UIFramework;
using Dundas.Dashboard.Controls;
using Dundas.Dashboard.DashboardControls.Extensibility;
using Dundas.Dashboard.BusinessService;

namespace HtmlExport { /// /// Html export plug-in class. /// public class HtmlExport : IDashboardExport { #region Constants

/// /// Gets the plugin title. /// /// The plugin title. public static string PluginTitle { get { return "Html Export"; } }

/// /// Message to show on success. /// public static string ExportSuccessMessage = "Html file successfully created.";

/// /// Message to show on error. /// public static string ExportErrorMessage = "An error occured trying to export to html file."; #endregion

#region Constructors

/// /// Initializes a new instance of the class. /// public HtmlExport() { HtmlExport.HtmlOptionsWizard = new HtmlOptionsWizard(); } #endregion

#region IDashboardExport Members

/// /// The call to export the dashboard. /// /// The images to export. This might be for the entire dashboard, a single control or multiple /// controls depending on what the plug-in supports and what the user has selected. /// The data to export. This may be the data for the entire dashboard (all controls on dashboard), /// a single control or multiple controls depending on what the plug-in supports and what the user has selected. /// A reference to the output filestream that the user has selected. This stream should be closed /// by the plug-in when it is finished, as it will not be closed by Dundas Dashboard in case the plug-in requires async /// activity. /// if set to true then the entire dashboard is selected. public void ExportDashboard(Dictionary imagesToExport, Dictionary dataToExport, Stream outputFileStream, bool isEntireDashboard) { try { // Create the Html document HtmlExport.HtmlDocument = new Html.Document { DocumentTitle = HtmlOptionsWizard.Options.DocumentTitle, IsAlternatingRow = HtmlOptionsWizard.Options.IsAlternatingRow, HeaderCellColor = HtmlExport.ColorToHtml(HtmlOptionsWizard.Options.HeaderCellColor) };

// Loop through all DVs and export them one by one foreach (string dataKey in dataToExport.Keys) { // Get the data to export DataResultCollection dataResults = dataToExport[dataKey];

// Export the result to table this.ExportDataResultToTable(dataKey, dataResults.First()); }

// Save the document if (!HtmlExport.HtmlDocument.Save(outputFileStream)) { throw new Exception(HtmlExport.ExportErrorMessage); }

// Show success message box MessageBox msgBox = new MessageBox { Buttons = MessageBoxButtons.OK, Title = HtmlExport.PluginTitle, Icon = MessageBoxIcon.Information, Message = HtmlExport.ExportSuccessMessage };

msgBox.Show(); } catch (Exception ex) { // Show exception message box MessageHelper.ShowException(ex); } finally { // Close the output stream outputFileStream.Close(); } } #endregion

#region IDashboardExportBase Members

/// /// Gets the default extension for the file being saved. For example, "csv". /// /// The default extension for the file being saved. public string DefaultExt { get { return "html"; } }

/// /// Gets the display name of the export plug-in. This will show up in the export wizard. /// /// The name of the export plug-in. public string ExportPluginDisplayName { get { return HtmlExport.PluginTitle; } }

/// /// Gets the file type filter. This is the filter given to the save dialog to allow the user to select the file to save. /// The expected format is, using CSV as an example, "CSV Files|*.csv". /// /// The file type filter. public string FileTypeFilter { get { return "Html Files (*.htm;*.html)|*.htm;*.html"; } }

/// /// Gets a value indicating whether this instance supports the entire dashboard as an option for the user to select. /// /// /// true if this instance supports the entire dashboard being exported; otherwise, false. /// public bool IsDashboardSelectionSupported { get { return true; } }

/// /// Gets a value indicating whether this instance supports the user selecting multiple disjoint controls. /// /// /// true if this instance supports multiple controls being selected by the user; otherwise, false. /// public bool IsMultipleControlSelectionSupported { get { return true; } }

/// /// Gets a value indicating whether this instance supports the user selecting a single control. /// /// /// true if this instance supports the user selecting a single control; otherwise, false. /// public bool IsSingleControlSelectionSupported { get { return true; } }

/// /// Gets a wizard that can be launched by the user to show extra information to them. If this is null, then /// the option will not be presented. /// /// The wizard. public IDashboardExportWizard Wizard { get { return HtmlExport.HtmlOptionsWizard; } } #endregion

#region Properties

/// /// Gets or sets the HTML options wizard. /// /// The HTML options wizard. public static HtmlOptionsWizard HtmlOptionsWizard { get; set; }

/// /// Gets or sets the HTML document. /// /// The HTML document. public static Html.Document HtmlDocument { get; set; } #endregion

#region Methods

/// /// Exports the data result to table. /// /// The result key. /// The data result. /// private bool ExportDataResultToTable(string resultKey, DataResult dataResult) { // Do not export empty data results or blank keys. if (dataResult == null || string.IsNullOrEmpty(resultKey)) { return false; }

// Add a new table to document Html.Table table = HtmlExport.HtmlDocument.AddTable();

// Get header and row count int headerCount = dataResult.Fields.Count; int detailCount = dataResult.DataPoints.Count;

// Write the root header table.THead.AddRow().AddCell(resultKey, "hh", headerCount);

// Write the header of this KPI Html.TrH headRow = table.THead.AddRow(); for (int colIndex = 0; colIndex < headerCount; colIndex++) { string cellValue = dataResult.Fields[colIndex].Name;

headRow.AddCell(cellValue, "h"); }

// Loop through all datapoints for (int rowIndex = 0; rowIndex < detailCount; rowIndex++) { // Add a new row for each set of points Html.TrB bodyRow = table.TBody.AddRow();

for (int colIndex = 0; colIndex < headerCount; colIndex++) { // Get variables for data point DataPoint dataPoint = dataResult.DataPoints[rowIndex]; DataField dataField = dataResult.Fields[colIndex]; DatabaseTypeData typeData = dataField.DataType; object fieldValue = dataPoint.FieldValues[colIndex];

// Set the value, style and data type to defaults. string value = fieldValue.ToString();

// Determine the type of value this field represents. Use it to format the value. switch (typeData.DataTypeCode) { case DatabaseTypeCode.DateTime: { DateTime dateValue;

if (DateTime.TryParse(value, out dateValue)) { value = dateValue.ToOADate().ToString(CultureInfo.InvariantCulture); } } break;

case DatabaseTypeCode.Double: case DatabaseTypeCode.Decimal: case DatabaseTypeCode.Currency: { decimal decimalValue;

if (decimal.TryParse(value, out decimalValue)) { value = decimalValue.ToString((typeData.DataTypeCode == DatabaseTypeCode.Currency) ? "$###,###,##0.00" : string.Empty, CultureInfo.InvariantCulture); } } break; }

// Add the cell and adjust for alternating row bodyRow.AddCell(value, HtmlExport.HtmlDocument.IsAlternatingRow ? ((rowIndex % 2 == 0) ? "d" : "d1") : "d", 0); } }

// Add a blank row at the end of the table table.TBody.AddRow().AddCell(" ", "d", headerCount);

return true; }

/// /// Converts a Color object to Html hex format. /// /// The color. /// Color in html hex format. public static string ColorToHtml(Color color) { string alpha = (color.A < 255) ? string.Format(CultureInfo.InvariantCulture, "{0:x2}", color.A) : string.Empty;

return string.Format(CultureInfo.InvariantCulture, "#{0}{1:x2}{2:x2}{3:x2}", alpha, color.R, color.G, color.B); } #endregion } }

Simplified Image Export code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Dundas.Dashboard.Business;
using Dundas.Dashboard.Controls;
using Dundas.Dashboard.DashboardControls.Extensibility;
using Dundas.Dashboard.Extensibility;
using Dundas.Dashboard.UIFramework;
using ImageTools;
using ImageTools.IO.Jpeg;

namespace JpegExport { /// /// Jpeg export plug-in class. /// public class JpegExport : IDashboardExport { #region Constants

/// /// Gets the plugin title. /// /// The plugin title. public static string PluginTitle { get { return "Jpeg Export"; } }

/// /// Message to show on success. /// public static string ExportSuccessMessage = "Jpeg file successfully created."; #endregion

#region IDashboardExport Members /// /// The call to export the dashboard. /// /// The images to export. This might be for the entire dashboard, a single control or multiple /// controls depending on what the plug-in supports and what the user has selected. /// The data to export. This may be the data for the entire dashboard (all controls on dashboard), /// a single control or multiple controls depending on what the plug-in supports and what the user has selected. /// A reference to the output filestream that the user has selected. This stream should be closed /// by the plug-in when it is finished, as it will not be closed by Dundas Dashboard in case the plug-in requires async /// activity. /// if set to true then the entire dashboard is selected. public void ExportDashboard(Dictionary imagesToExport, Dictionary dataToExport, Stream outputFileStream, bool isEntireDashboard) { try { // Get the first bitmap (since we can only export one image to a stream) WriteableBitmap bitmap = imagesToExport.Values.First();

// Create a byte array from image data int[] imageData = bitmap.Pixels; byte[] bytes = new byte[imageData.Length * 4]; int offset = 0;

// The writeable bitmap pixel format is ARGB while ImageTools uses RGBA so we need to convert foreach (int pixel in imageData) { bytes[offset++] = (byte)(pixel >> 16); bytes[offset++] = (byte)(pixel >> 8); bytes[offset++] = (byte)(pixel >> 0); bytes[offset++] = (byte)(pixel >> 24); }

// Create a new bitmap from pixel data ExtendedImage image = new ExtendedImage(bitmap.PixelWidth, bitmap.PixelHeight); image.SetPixels(bitmap.PixelWidth, bitmap.PixelHeight, bytes);

// Get the jepg encoder, set quality to 100% and save image to stream JpegEncoder encoder = new JpegEncoder { Quality = 100 }; encoder.Encode(image, outputFileStream);

// Show success message box MessageBox msgBox = new MessageBox { Buttons = MessageBoxButtons.OK, Title = JpegExport.PluginTitle, Icon = MessageBoxIcon.Information, Message = JpegExport.ExportSuccessMessage };

msgBox.Show(); } catch (Exception ex) { // Show exception message box MessageHelper.ShowException(ex); } finally { // Close the output stream outputFileStream.Close(); } } #endregion

#region IDashboardExportBase Members

/// /// Gets the default extension for the file being saved. For example, "csv". /// /// The default extension for the file being saved. public string DefaultExt { get { return "jpg"; } }

/// /// Gets the display name of the export plug-in. This will show up in the export wizard. /// /// The name of the export plug-in. public string ExportPluginDisplayName { get { return JpegExport.PluginTitle; } }

/// /// Gets the file type filter. This is the filter given to the save dialog to allow the user to select the file to save. /// The expected format is, using CSV as an example, "CSV Files|*.csv". /// /// The file type filter. public string FileTypeFilter { get { return "Jpeg Files (*.jpg)|*.jpg"; } }

/// /// Gets a value indicating whether this instance supports the entire dashboard as an option for the user to select. /// /// /// true if this instance supports the entire dashboard being exported; otherwise, false. /// public bool IsDashboardSelectionSupported { get { return true; } }

/// /// Gets a value indicating whether this instance supports the user selecting multiple disjoint controls. /// /// /// true if this instance supports multiple controls being selected by the user; otherwise, false. /// public bool IsMultipleControlSelectionSupported { get { return false; } }

/// /// Gets a value indicating whether this instance supports the user selecting a single control. /// /// /// true if this instance supports the user selecting a single control; otherwise, false. /// public bool IsSingleControlSelectionSupported { get { return true; } }

/// /// Gets a wizard that can be launched by the user to show extra information to them. If this is null, then /// the option will not be presented. /// /// The wizard. public IDashboardExportWizard Wizard { get { return null; } } #endregion } }

Downloads

DashboardExportSample.zip - Dashboard Export Visual Studio 2010 Solution
  Name Size
- DashboardExportSample.zip 11.17 MB

About Dundas | Contact Us Follow us on Twitter! | Privacy Statement | Report Site Issues

Copyright © 2009-2014 Dundas Data Visualization, Inc.