Table of Contents

Exporting Web Services (VB.Net / netframework)

Note

This demo is available in your FlexCel installation at <FlexCel Install Folder>\samples\vb\VS2022\netframework\20.Reports\27.Exporting Web Services and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​NET-​demos/​tree/​master/​vb/​VS2022/​netframework/​Modules/​20.​Reports/​27.​Exporting Web Services

Overview

A demo that accesses the NOAA Meteorological web service and returns an Excel file with the forecast. Just in case you do not have an Internet connection available, some sample data is included to work offline too.

Concepts

How to export the data on a Web Service to Excel or PDF.

Files

AssemblyInfo.vb

Imports System.Reflection
Imports System.Runtime.CompilerServices

'
' General Information about an assembly is controlled through the following 
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
'
<Assembly: AssemblyTitle("")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyConfiguration("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("")>
<Assembly: AssemblyCopyright("(c) 2002 - 2014 TMS Software")>
<Assembly: AssemblyTrademark("")>
<Assembly: AssemblyCulture("")>

'
' Version information for an assembly consists of the following four values:
'
'      Major Version
'      Minor Version 
'      Build Number
'      Revision
'
' You can specify all the values or you can default the Revision and Build Numbers 
' by using the '*' as shown below:

<Assembly: AssemblyVersion("6.2.1.0")>

'
' In order to sign your assembly you must specify a key to use. Refer to the 
' Microsoft .NET Framework documentation for more information on assembly signing.
'
' Use the attributes below to control which key is used for signing. 
'
' Notes: 
'   (*) If no key is specified, the assembly is not signed.
'   (*) KeyName refers to a key that has been installed in the Crypto Service
'       Provider (CSP) on your machine. KeyFile refers to a file which contains
'       a key.
'   (*) If the KeyFile and the KeyName values are both specified, the 
'       following processing occurs:
'       (1) If the KeyName can be found in the CSP, that key is used.
'       (2) If the KeyName does not exist and the KeyFile does exist, the key 
'           in the KeyFile is installed into the CSP and used.
'   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
'       When specifying the KeyFile, the location of the KeyFile should be
'       relative to the project output directory which is
'       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
'       located in the project directory, you would specify the AssemblyKeyFile 
'       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
'   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
'       documentation for more information on this.
'
<Assembly: AssemblyDelaySign(False)>
<Assembly: AssemblyKeyFile("")>
<Assembly: AssemblyKeyName("")>

Form1.Designer.vb

Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Imports System.Reflection
Imports System.Xml
Imports System.Net
Imports System.Threading
Imports FlexCel.Core
Imports FlexCel.XlsAdapter
Imports FlexCel.Report
Imports FlexCel.Render
Namespace ExportingWebServices
    Partial Public Class mainForm
        Inherits System.Windows.Forms.Form

        ''' <summary>
        ''' Required designer variable.
        ''' </summary>
        Private components As System.ComponentModel.Container = Nothing

        ''' <summary>
        ''' Clean up any resources being used.
        ''' </summary>
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If components IsNot Nothing Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

#Region "Windows Form Designer generated code"
        ''' <summary>
        ''' Required method for Designer support - do not modify
        ''' the contents of this method with the code editor.
        ''' </summary>
        Private Sub InitializeComponent()
            Me.btnExportXls = New System.Windows.Forms.Button()
            Me.saveFileDialogXls = New System.Windows.Forms.SaveFileDialog()
            Me.reportStart = New FlexCel.Report.FlexCelReport()
            Me.btnCancel = New System.Windows.Forms.Button()
            Me.label3 = New System.Windows.Forms.Label()
            Me.cbOffline = New System.Windows.Forms.CheckBox()
            Me.btnExportPdf = New System.Windows.Forms.Button()
            Me.saveFileDialogPdf = New System.Windows.Forms.SaveFileDialog()
            Me.edcity = New System.Windows.Forms.ComboBox()
            Me.SuspendLayout()
            ' 
            ' btnExportXls
            ' 
            Me.btnExportXls.Anchor = (CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles))
            Me.btnExportXls.BackColor = System.Drawing.Color.Green
            Me.btnExportXls.ForeColor = System.Drawing.Color.White
            Me.btnExportXls.Location = New System.Drawing.Point(16, 120)
            Me.btnExportXls.Name = "btnExportXls"
            Me.btnExportXls.Size = New System.Drawing.Size(112, 23)
            Me.btnExportXls.TabIndex = 0
            Me.btnExportXls.Text = "Export to Excel"
            Me.btnExportXls.UseVisualStyleBackColor = False
            '			Me.btnExportXls.Click += New System.EventHandler(Me.btnExportXls_Click)
            ' 
            ' saveFileDialogXls
            ' 
            Me.saveFileDialogXls.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm|Excel 97/2003|*.xls|Excel 2007|*.xlsx;*.xlsm|All " & "files|*.*"
            Me.saveFileDialogXls.RestoreDirectory = True
            ' 
            ' reportStart
            ' 
            Me.reportStart.AllowOverwritingFiles = True
            Me.reportStart.DeleteEmptyRanges = False
            ' 
            ' btnCancel
            ' 
            Me.btnCancel.Anchor = (CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles))
            Me.btnCancel.BackColor = System.Drawing.Color.FromArgb((CInt((CByte(192)))), (CInt((CByte(0)))), (CInt((CByte(0)))))
            Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
            Me.btnCancel.ForeColor = System.Drawing.Color.White
            Me.btnCancel.Location = New System.Drawing.Point(272, 120)
            Me.btnCancel.Name = "btnCancel"
            Me.btnCancel.Size = New System.Drawing.Size(112, 23)
            Me.btnCancel.TabIndex = 3
            Me.btnCancel.Text = "Cancel"
            Me.btnCancel.UseVisualStyleBackColor = False
            '			Me.btnCancel.Click += New System.EventHandler(Me.btnCancel_Click)
            ' 
            ' label3
            ' 
            Me.label3.Location = New System.Drawing.Point(32, 19)
            Me.label3.Name = "label3"
            Me.label3.Size = New System.Drawing.Size(40, 85)
            Me.label3.TabIndex = 8
            Me.label3.Text = "City:"
            ' 
            ' cbOffline
            ' 
            Me.cbOffline.Checked = True
            Me.cbOffline.CheckState = System.Windows.Forms.CheckState.Checked
            Me.cbOffline.Location = New System.Drawing.Point(32, 80)
            Me.cbOffline.Name = "cbOffline"
            Me.cbOffline.Size = New System.Drawing.Size(352, 24)
            Me.cbOffline.TabIndex = 10
            Me.cbOffline.Text = "Use offline data. (do not actually connect to the web service)"
            ' 
            ' btnExportPdf
            ' 
            Me.btnExportPdf.Anchor = (CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles))
            Me.btnExportPdf.BackColor = System.Drawing.Color.SteelBlue
            Me.btnExportPdf.ForeColor = System.Drawing.Color.White
            Me.btnExportPdf.Location = New System.Drawing.Point(144, 120)
            Me.btnExportPdf.Name = "btnExportPdf"
            Me.btnExportPdf.Size = New System.Drawing.Size(112, 23)
            Me.btnExportPdf.TabIndex = 11
            Me.btnExportPdf.Text = "Export to Pdf"
            Me.btnExportPdf.UseVisualStyleBackColor = False
            '			Me.btnExportPdf.Click += New System.EventHandler(Me.btnExportPdf_Click)
            ' 
            ' saveFileDialogPdf
            ' 
            Me.saveFileDialogPdf.Filter = "Pdf Files|*.pdf"
            Me.saveFileDialogPdf.RestoreDirectory = True
            ' 
            ' edcity
            ' 
            Me.edcity.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend
            Me.edcity.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems
            Me.edcity.FormattingEnabled = True
            Me.edcity.Location = New System.Drawing.Point(78, 12)
            Me.edcity.MaxDropDownItems = 32
            Me.edcity.Name = "edcity"
            Me.edcity.Size = New System.Drawing.Size(306, 21)
            Me.edcity.TabIndex = 12
            '			Me.edcity.KeyDown += New System.Windows.Forms.KeyEventHandler(Me.edcity_KeyDown)
            ' 
            ' mainForm
            ' 
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(416, 157)
            Me.Controls.Add(Me.edcity)
            Me.Controls.Add(Me.btnExportPdf)
            Me.Controls.Add(Me.cbOffline)
            Me.Controls.Add(Me.label3)
            Me.Controls.Add(Me.btnCancel)
            Me.Controls.Add(Me.btnExportXls)
            Me.Name = "mainForm"
            Me.Text = "Exporting Web Services"
            Me.ResumeLayout(False)

        End Sub
#End Region

        Private WithEvents btnCancel As System.Windows.Forms.Button
        Private label3 As System.Windows.Forms.Label
        Private cbOffline As System.Windows.Forms.CheckBox
        Private WithEvents btnExportXls As System.Windows.Forms.Button
        Private WithEvents btnExportPdf As System.Windows.Forms.Button
        Private saveFileDialogXls As System.Windows.Forms.SaveFileDialog
        Private saveFileDialogPdf As System.Windows.Forms.SaveFileDialog
        Private reportStart As FlexCel.Report.FlexCelReport
        Private WithEvents edcity As ComboBox

    End Class
End Namespace



Form1.vb

'This program is inspired on the progam by Mikhail Arkhipov
' * at http://blogs.msdn.com/mikhailarkhipov/archive/2004/08/12/213963.aspx
' * Thanks!
' 

' UPDATE: This was patched with the info on 
' * http://weblogs.asp.net/jan/archive/2004/01/28/63771.aspx
' * to make it work.
' * 
' * Thanks again...
' * 
' * UPDATE 2!
' * The NOAA broke the service again, and it has not fixed it for more than a year. 
' * I give up. We will use http://www.webservicex.net/WeatherForecast.asmx instead.
' * The code for NOAA is still there on the SetupNOAA method, just not used so you can see it (and try it if it ever starts working again)
' *
' * UPDATE 3!
' * Now WebserviceX is not working, going back to NOAA. As you can see, it isn't very trustable that a webservice will be there in the
' * future, so this demo might not work in online mode when you try it. But you can always look at in in offline mode.
' * 


Imports System.ComponentModel
Imports System.IO
Imports System.Reflection
Imports System.Xml
Imports System.Net
Imports System.Threading

Imports FlexCel.Core
Imports FlexCel.XlsAdapter
Imports FlexCel.Report
Imports FlexCel.Render

Imports gov.weather.www
Imports System.Globalization

Namespace ExportingWebServices
	''' <summary>
	''' An example that will read data from a webservice.
	''' </summary>
	Partial Public Class mainForm
		Inherits System.Windows.Forms.Form

		Private Cities As New Dictionary(Of String, LatLong)(StringComparer.CurrentCultureIgnoreCase)
		Public Sub New()
			InitializeComponent()
			LoadCities()
		End Sub

		Private Sub LoadCities()
			Dim xml As New XmlDocument()
				Dim DataPath As String = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), ".."), "..") & Path.DirectorySeparatorChar
				xml.Load(Path.Combine(DataPath, "cities.xml"))
				Dim latLonList As XmlNodeList = xml.GetElementsByTagName("latLonList")
				Dim cityNameList As XmlNodeList = xml.GetElementsByTagName("cityNameList")

				If latLonList.Count <> 1 Then
					Throw New Exception("Invalid city list")
				End If
				If cityNameList.Count <> 1 Then
					Throw New Exception("Invalid city list")
				End If

				Dim lats As String = latLonList.Item(0).InnerText
				Dim cits As String = cityNameList.Item(0).InnerText

				Dim latsParsed() As String = lats.Split(" "c)
				Dim citsParsed() As String = cits.Split("|"c)

				If citsParsed.Length <> latsParsed.Length Then
					Throw New Exception("Invalid city list")
				End If

				edcity.BeginUpdate()
				Try
					For i As Integer = 0 To citsParsed.Length - 1
						Dim ll() As String = latsParsed(i).Split(","c)
						If ll.Length <> 2 Then
							Throw New Exception("Invalid city list")
						End If
						Cities.Add(citsParsed(i), New LatLong(Convert.ToDecimal(ll(0), CultureInfo.InvariantCulture), Convert.ToDecimal(ll(1), CultureInfo.InvariantCulture)))
						edcity.Items.Add(citsParsed(i))
					Next i

					edcity.Text = "New York,NY"
				Finally
					edcity.EndUpdate()
				End Try

		End Sub

		Private Sub Export(ByVal SaveDialog As SaveFileDialog, ByVal ToPdf As Boolean)
			Try
				Dim DataPath As String = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), ".."), "..") & Path.DirectorySeparatorChar

				'We will use a thread to connect, to avoid "freezing" the GUI
				Dim MyWebConnect As New WebConnectThread(reportStart, edcity.Text, DataPath, cbOffline.Checked, Cities)
				Dim WebConnect As New Thread(New ThreadStart(AddressOf MyWebConnect.SetupNOAA))
				WebConnect.Start()
				Using Pg As New ProgressDialog()
					Pg.ShowProgress(WebConnect)
					If MyWebConnect IsNot Nothing AndAlso MyWebConnect.MainException IsNot Nothing Then
						Throw MyWebConnect.MainException
					End If
				End Using


				If SaveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
					If ToPdf Then
						Dim xls As New XlsFile()
						xls.Open(DataPath & "Exporting Web Services.template.xls")
						reportStart.Run(xls)
						Using PdfExport As New FlexCelPdfExport(xls, True)
							PdfExport.Export(SaveDialog.FileName)
						End Using
					Else
						reportStart.Run(DataPath & "Exporting Web Services.template.xls", SaveDialog.FileName)
					End If

					If MessageBox.Show("Do you want to open the generated file?", "Confirm", MessageBoxButtons.YesNo) = System.Windows.Forms.DialogResult.Yes Then
						Process.Start(SaveDialog.FileName)
					End If
				End If
			Catch ex As Exception
				MessageBox.Show(ex.Message)
			End Try

		End Sub


		Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
			Close()
		End Sub

		Private Sub btnExportPdf_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportPdf.Click
			Export(saveFileDialogPdf, True)
		End Sub

		Private Sub btnExportXls_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportXls.Click
			Export(saveFileDialogXls, False)
		End Sub

		Private Sub edcity_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles edcity.KeyDown
			edcity.DroppedDown = False
		End Sub

	End Class

	Friend Structure LatLong
		Public Latitude As Decimal
		Public Longitude As Decimal

		Public Sub New(ByVal aLatitude As Decimal, ByVal aLongitude As Decimal)
			Latitude = aLatitude
			Longitude = aLongitude
		End Sub
	End Structure

	Friend Class WebConnectThread
		Private CityName As String
		Private DataPath As String
		Private UseOfflineData As Boolean
		Private Cities As Dictionary(Of String, LatLong)
		Private ReportStart As FlexCelReport
		Private FMainException As Exception

		Public Sub New(ByVal aReportStart As FlexCelReport, ByVal aCityName As String, ByVal aDataPath As String, ByVal aUseOfflineData As Boolean, ByVal aCities As Dictionary(Of String, LatLong))
			CityName = aCityName
			DataPath = aDataPath
			UseOfflineData = aUseOfflineData
			ReportStart = aReportStart
			Cities = aCities
		End Sub


		Public Sub SetupNOAA()
			Try
				SetupNOAA(ReportStart, CityName, DataPath, UseOfflineData, Cities)
			Catch ex As Exception
				FMainException = ex
			End Try

		End Sub

		Public Shared Sub SetupNOAA(ByVal reportStart As FlexCelReport, ByVal CityName As String, ByVal DataPath As String, ByVal UseOfflineData As Boolean, ByVal Cities As Dictionary(Of String, LatLong))
			Dim CityCoords As LatLong
			GetCity(Cities, CityName, CityCoords)
			reportStart.SetValue("Date", Date.Now)
			Dim forecasts As String
			Dim dtStart As Date = Date.Now

			If UseOfflineData Then
				Using fs As New StreamReader(Path.Combine(DataPath, "OfflineData.xml"))
					forecasts = fs.ReadToEnd()
				End Using
			Else
				Dim nd As New ndfdXML()
				forecasts = nd.NDFDgen(CityCoords.Latitude, CityCoords.Longitude, productType.glance, dtStart, dtStart.AddDays(7), unitType.m, New weatherParametersType())

#If(SAVEOFFLINEDATA) Then
				Using sw As New StreamWriter(Path.Combine(DataPath, "OfflineData.xml"))
					sw.Write(forecasts)
				End Using
#End If
			End If

			If String.IsNullOrEmpty(forecasts) Then
				Throw New Exception("Can't find the place " & CityName)
			End If

			Dim ds As New DataSet()
			'Load the data into a dataset. On this web service, we cannot just call DataSet.ReadXml as the data is not on the correct format.
			Dim xmlDoc As New XmlDocument()
				xmlDoc.LoadXml(forecasts)
				Dim HighList As XmlNodeList = xmlDoc.SelectNodes("/dwml/data/parameters/temperature[@type='maximum']/value/text()")
				Dim LowList As XmlNodeList = xmlDoc.SelectNodes("/dwml/data/parameters/temperature[@type='minimum']/value/text()")
				Dim IconList As XmlNodeList = xmlDoc.SelectNodes("/dwml/data/parameters/conditions-icon/icon-link/text()")

				Dim WeatherTable As DataTable = ds.Tables.Add("Weather")

				WeatherTable.Columns.Add("Day", GetType(Date))
				WeatherTable.Columns.Add("Low", GetType(Double))
				WeatherTable.Columns.Add("High", GetType(Double))
				WeatherTable.Columns.Add("Icon", GetType(Byte()))

				For i As Integer = 0 To Math.Min(Math.Min(HighList.Count, LowList.Count), IconList.Count) - 1
					WeatherTable.Rows.Add(New Object(){ dtStart.AddDays(i), Convert.ToDouble(LowList(i).Value), Convert.ToDouble(HighList(i).Value), LoadIcon(IconList(i).Value, UseOfflineData, DataPath)})
				Next i


			reportStart.AddTable(ds, TDisposeMode.DisposeAfterRun)
			reportStart.SetValue("Latitude", CityCoords.Latitude)
			reportStart.SetValue("Longitude", CityCoords.Longitude)
			reportStart.SetValue("Place", CityName)

		End Sub

		Private Shared Sub GetCity(ByVal Cities As Dictionary(Of String, LatLong), ByVal CityName As String, ByRef CityCoords As LatLong)
			If Not Cities.TryGetValue(CityName, CityCoords) Then
				Throw New Exception("Can't find the city " & CityName)
			End If
		End Sub

		Friend ReadOnly Property MainException() As Exception
			Get
				Return FMainException
			End Get
		End Property

		Friend Shared Function LoadIcon(ByVal url As String, ByVal useOfflineData As Boolean, ByVal dataPath As String) As Byte()
			If url Is Nothing OrElse url.Length = 0 Then
				Return Nothing 'no icon for this image.
			End If

			If useOfflineData Then
				Dim u As New Uri(url)
				Return LoadFileIcon(Path.Combine(dataPath, u.Segments(u.Segments.Length - 1)))
			Else
#If (SAVEOFFLINEDATA) Then
				Dim u As New Uri(url)
				Dim IconData() As Byte = LoadWebIcon(url)
				Using fs As New FileStream(Path.Combine(dataPath, u.Segments(u.Segments.Length - 1)), FileMode.Create)
					fs.Write(IconData, 0, IconData.Length)
				End Using
#End If

				Return LoadWebIcon(url)

			End If
		End Function

		''' <summary>
		''' On a real implementation this should be cached.
		''' </summary>
		''' <param name="url"></param>
		''' <returns></returns>
		Friend Shared Function LoadWebIcon(ByVal url As String) As Byte()
			Using wc As New WebClient()
				wc.Headers.Add("user-agent", "FlexCel Webservice Example")
				Return wc.DownloadData(url)
			End Using
		End Function

		Private Shared Function LoadFileIcon(ByVal filename As String) As Byte()
			Using fs As New FileStream(filename, FileMode.Open)
				Dim Result(CInt(fs.Length) - 1) As Byte
				fs.Read(Result, 0, Result.Length)
				Return Result
			End Using
		End Function


	End Class

End Namespace

Program.vb

Namespace ExportingWebServices
	Friend NotInheritable Class Program

		Private Sub New()
		End Sub

		''' <summary>
		''' The main entry point for the application.
		''' </summary>
		<STAThread> _
		Shared Sub Main()
			Application.EnableVisualStyles()
			Application.SetCompatibleTextRenderingDefault(False)
			Application.Run(New mainForm())
		End Sub
	End Class
End Namespace

ProgressDialog.Designer.vb

Imports System.Collections
Imports System.ComponentModel
Imports System.Threading
Imports FlexCel.Render
Namespace ExportingWebServices
	Partial Public Class ProgressDialog
		Inherits System.Windows.Forms.Form

		Private statusBar1 As System.Windows.Forms.StatusBar
		Private statusBarPanel1 As System.Windows.Forms.StatusBarPanel
		Private statusBarPanelTime As System.Windows.Forms.StatusBarPanel
		Private labelCaption As System.Windows.Forms.Label
		''' <summary>
		''' Required designer variable.
		''' </summary>
		Private components As System.ComponentModel.Container = Nothing

		''' <summary>
		''' Clean up any resources being used.
		''' </summary>
		Protected Overrides Sub Dispose(ByVal disposing As Boolean)
			If disposing Then
				If components IsNot Nothing Then
					components.Dispose()
				End If
			End If
			MyBase.Dispose(disposing)
		End Sub

		#Region "Windows Form Designer generated code"
		''' <summary>
		''' Required method for Designer support - do not modify
		''' the contents of this method with the code editor.
		''' </summary>
		Private Sub InitializeComponent()
			Me.statusBar1 = New System.Windows.Forms.StatusBar()
			Me.statusBarPanel1 = New System.Windows.Forms.StatusBarPanel()
			Me.statusBarPanelTime = New System.Windows.Forms.StatusBarPanel()
			Me.labelCaption = New System.Windows.Forms.Label()
			Me.timer1 = New System.Timers.Timer()
			CType(Me.statusBarPanel1, System.ComponentModel.ISupportInitialize).BeginInit()
			CType(Me.statusBarPanelTime, System.ComponentModel.ISupportInitialize).BeginInit()
			CType(Me.timer1, System.ComponentModel.ISupportInitialize).BeginInit()
			Me.SuspendLayout()
			' 
			' statusBar1
			' 
			Me.statusBar1.Location = New System.Drawing.Point(0, 100)
			Me.statusBar1.Name = "statusBar1"
			Me.statusBar1.Panels.AddRange(New System.Windows.Forms.StatusBarPanel() { Me.statusBarPanel1, Me.statusBarPanelTime})
			Me.statusBar1.ShowPanels = True
			Me.statusBar1.Size = New System.Drawing.Size(448, 22)
			Me.statusBar1.TabIndex = 1
			' 
			' statusBarPanel1
			' 
			Me.statusBarPanel1.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.None
			Me.statusBarPanel1.Text = "Elapsed Time:"
			Me.statusBarPanel1.Width = 80
			' 
			' statusBarPanelTime
			' 
			Me.statusBarPanelTime.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.None
			Me.statusBarPanelTime.Text = "0:00"
			' 
			' labelCaption
			' 
			Me.labelCaption.Anchor = (CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles))
			Me.labelCaption.Location = New System.Drawing.Point(16, 16)
			Me.labelCaption.Name = "labelCaption"
			Me.labelCaption.Size = New System.Drawing.Size(408, 16)
			Me.labelCaption.TabIndex = 2
			Me.labelCaption.Text = "Connecting to Webservice..."
			' 
			' timer1
			' 
			Me.timer1.Enabled = True
			Me.timer1.SynchronizingObject = Me
'			Me.timer1.Elapsed += New System.Timers.ElapsedEventHandler(Me.timer1_Elapsed)
			' 
			' ProgressDialog
			' 
			Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
			Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
			Me.ClientSize = New System.Drawing.Size(448, 122)
			Me.Controls.Add(Me.labelCaption)
			Me.Controls.Add(Me.statusBar1)
			Me.Name = "ProgressDialog"
			Me.ShowInTaskbar = False
			Me.Text = "Please wait..."
'			Me.Closed += New System.EventHandler(Me.ProgressDialog_Closed)
			CType(Me.statusBarPanel1, System.ComponentModel.ISupportInitialize).EndInit()
			CType(Me.statusBarPanelTime, System.ComponentModel.ISupportInitialize).EndInit()
			CType(Me.timer1, System.ComponentModel.ISupportInitialize).EndInit()
			Me.ResumeLayout(False)

		End Sub
		#End Region
	End Class
End Namespace


ProgressDialog.vb

Imports System.Collections
Imports System.ComponentModel

Imports System.Threading

Imports FlexCel.Render

Namespace ExportingWebServices
	''' <summary>
	''' A dialog box to show progress. This could be done with a BackgroundWorker, it was done this way for .NET 1.1 compatibility.
	''' </summary>
	Partial Public Class ProgressDialog
		Inherits System.Windows.Forms.Form

		Private WithEvents timer1 As System.Timers.Timer

		Public Sub New()
			InitializeComponent()
		End Sub


		Private StartTime As Date
		Private RunningThread As Thread

		Private Sub timer1_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles timer1.Elapsed
			UpdateStatus()
		End Sub

		Public Sub ShowProgress(ByVal aRunningThread As Thread)
			RunningThread = aRunningThread

			If Not RunningThread.IsAlive Then
				DialogResult = System.Windows.Forms.DialogResult.OK
				Return
			End If
			timer1.Enabled = True
			StartTime = Date.Now
			ShowDialog()
		End Sub

		Private Sub UpdateStatus()
			Dim ts As TimeSpan = Date.Now.Subtract(StartTime)
			Dim hours As String
			If ts.Hours = 0 Then
				hours = ""
			Else
				hours = ts.Hours.ToString("00") & ":"
			End If
			statusBarPanelTime.Text = hours & ts.Minutes.ToString("00") & ":" & ts.Seconds.ToString("00")

			If Not RunningThread.IsAlive Then
				DialogResult = System.Windows.Forms.DialogResult.OK
			End If
		End Sub

		Private Sub ProgressDialog_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
			timer1.Enabled = False
		End Sub

	End Class
End Namespace