同伴
创建Ordermate的目的是简化根据电影“产品”要求构建物料发票的过程。这种情况的参与者是:发行公司员工(即用户),剧院公司联系人(即客户)。Ordermate涵盖了以下电影订单处理工作流程。
电影院“客户”要求下订单订购一部或多部电影。
发行公司的员工从“组合框”下拉菜单中选择“客户”。
从CheckedListBox中选择所需的产品。
员工输入订购的物料数量。
员工单击[添加]按钮以更新表格。
员工可以选择在屏幕上查看发票和/或将发票导出到MicrosoftExcel。
目的
Ordermate演示了如何将xml用作平面文件类型数据存储。可以将XML转换,格式化并导入到您选择的任何类型的数据库(即MSAccess,SQLServer,Oracle,MYSQL等)中。使用XML序列化的.NET应用程序。它演示了中级VB.NET程序员入门的各种编程主题。涵盖的主题:
XmlSerializer:在XML文档中对对象进行序列化和反序列化。
PrintDocument:为“打印”和“打印预览”创建自定义发票表单。
DocumentFormat.OpenXml:打开XML格式以创建/输出Excel电子表格发票。
SpreadsheetLight:SpreadsheetLight是.NETFramework的开源OpenXML电子表格库。
DataBindings:数据绑定是在应用程序UI和业务对象之间建立连接的过程。
StringRandomGenerator:帮助生成随机发票编号。
Ordermate通常涉及以下内容:处理电影库存,创建发票,创建,编辑和更新产品供应。它可以用于读取/写入XML文件。XML输入/输出,并导出到MicrosoftExcel工作表。可以查看发票以进行“打印”和“打印预览”。读写XML。
背景
历史
实际上,Ordermate正在更新到我大约10年前创建的程序。由于客户需要重新格式化某些NessusScannerByTenable报告文件的格式,因此最近对其进行了重新审核。文件本身只是普通的xml数据集,需要将其提取,格式化并放入MicrosoftExcel电子表格中。
脚步
采取了以下步骤来基于现有xml文件生成类文件:
使用标准文本编辑器创建xml文件。
使用xsd.exe生成架构文件(*.xsd)。
-启动VisualStudio工具“开发人员命令提示符”
-格式化/正确的类型架构属性
使用xsd.exe从步骤2生成类文件
-xsdproducts.xsd/classes/language:VB
-xsdcustomer.xsd/classes/language:VB
清理生成的类文件(*.vb)
创建VisualStudio解决方案,包括(*.vb)个文件
XmlSerializer
数据收集类
所述DataCollection类表示XML文件的主机顶水平元件。XML文档中仅允许一个顶级元素。它包含对在反序列化xml文件中找到的所有Customer和Product对象的引用。一旦加载了所有产品和客户,它将触发PropertyChangedEvent一个侦听器(即表单控件)可以响应的。
Public Class DataCollection Implements System.ComponentModel.INotifyPropertyChanged Private _Products As List(Of Product) Private _Customers As List(Of Customer) ' These are the variables which will store data Public Property Products() As List(Of Product) Get Return _Products End Get Set(ByVal value As List(Of Product)) _Products = value RaisePropertyChanged("Products") End Set End Property Public Property Customers() As List(Of Customer) Get Return _Customers End Get Set(ByVal value As List(Of Customer)) _Customers = value RaisePropertyChanged("Customers") End Set End Property Public Event PropertyChanged As _ System.ComponentModel.PropertyChangedEventHandler _ Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged Protected Sub RaisePropertyChanged(ByVal propertyName As String) Dim propertyChanged As _ System.ComponentModel.PropertyChangedEventHandler _ = Me.PropertyChangedEvent If (propertyChanged IsNot Nothing) Then propertyChanged(Me, _ New System.ComponentModel.PropertyChangedEventArgs(propertyName)) End If End Sub End Class12345678910111213141516171819202122232425262728293031323334353637383940414243复制代码类型:[cpp]
反序列化
为了将数据从xml文件反序列化为类对象。我们需要利用XmlSerializer该类。该过程在
Initialize1复制代码类型:[cpp]
FrmMain类的方法。反序列化发生时,请连接一个EventHandler来接收和处理事件。
Private Sub Initialize() ' Initialize the Primary DataCollection _Data = New DataCollection ' FrmMain acts as a listener of events for the DataCollection class. ' Connect a EventHandler to receive and handle events raised by ' DataCollection class AddHandler _Data.PropertyChanged, AddressOf OnDataChanged ' Used to process two separate xml files Dim XmlDataCollection As DataCollection = Nothing ' Format used to load data from XML Dim format As New XmlSerializer(GetType(DataCollection)) ' Use the CustomerStream to Deserialize all Customer objects Using CustomerStream As Stream = _ File.OpenRead(DataDirectory & CustomersXml) XmlDataCollection = DirectCast(format.Deserialize(CustomerStream), _ DataCollection) If Not XmlDataCollection Is Nothing Then _Data.Customers = XmlDataCollection.Customers End If End Using ... End Sub123456789101112131415161718192021222324252627复制代码类型:[html]
序列化
相反的Deserialization是Serialization。序列化涉及将数据保存回xml文件。您可以再次使用XmlSerializer该类来执行此操作。每次对客户数据进行编辑时,都可以将其写回到硬盘上。对于FrmCustomer类,这是在SaveCustomers方法中完成的。
Private Sub SaveCustomers() ' Format used to load data from XML Dim serializer As New XmlSerializer(GetType(DataCollection)) Dim Data As New DataCollection Data.Customers = _Customers ' Create an XmlTextWriter using a FileStream. Using CustomerStream As Stream = _ New FileStream(DataDirectory & "Customers.xml", FileMode.Create) Dim writer As New XmlTextWriter(CustomerStream, Encoding.Unicode) serializer.Serialize(writer, Data) End Using End Sub1234567891011121314复制代码类型:[cpp]
打印文件
的PrintDocument类定义了发送输出到打印机,从Windows窗体应用程序进行打印时的可重复使用的对象。以下方法在屏幕上创建要打印的发票。
Private Sub CreateInvoiceDocument(ByVal g As Graphics) Dim srcRect As RectangleF = New Rectangle(0, 0, InvoiceSize.Width, _ InvoiceSize.Height) Dim nWidth As Integer = _ docInvoice.PrinterSettings.DefaultPageSettings.PaperSize.Width Dim nHeight As Integer = _ docInvoice.PrinterSettings.DefaultPageSettings.PaperSize.Height Dim destRect As RectangleF = New Rectangle(0, 0, nWidth, nHeight) Dim scalex As Single = CSng(destRect.Width / InvoiceSize.Width) Dim scaley As Single = CSng(destRect.Height / InvoiceSize.Height) Dim aPen As New Pen(Brushes.Black, 1) ' Draw the Invoice Image If picGroupLogo.BackgroundImage IsNot Nothing Then Dim gu As GraphicsUnit = GraphicsUnit.Pixel Dim scaledRectangle As RectangleF = GetScaledRectangle(scalex, _ scaley, picGroupLogo.Bounds) Dim myImage As Image = CType(picGroupLogo.BackgroundImage.Clone(), _ Image) g.DrawImage(myImage, scaledRectangle, _ picGroupLogo.BackgroundImage.GetBounds(gu), GraphicsUnit.Pixel) End If ' Draw out the Invoice Header WriteInvoiceHeader(g, scalex, scaley) ' Draw out the Invoice Line Items WriteInvoiceLineItems(g, scalex, scaley) End Sub1234567891011121314151617181920212223242526272829303132333435363738复制代码类型:[cpp]
电子表格灯
对于我来说,该程序最令人兴奋的部分可能是找到OpenSourceSpreadsheetLight[^]库。尽管源代码是用C#编写的,但我仍然喜欢这个漂亮的小实用程序。也许有一天以后,我会将其翻译成更明智的语言,例如VisualBasic(即VB.NET)。;-)除了SpreadsheetLight之外,所有笑话都很有用。以下是如何将发票数据导出到MicrosoftExcel电子表格的示例。使用预格式化的模板电子表格,并将发票数据放到其上。创建一个Helper类make可以很容易地格式化和处理最终输出。
Public Class Helper ... Private Sub Create(ByVal inInvoice As Invoice, info As FileInfo) ' SpreadsheetLight works on the idea of a currently selected worksheet. ' If no worksheet name is provided on opening an existing spreadsheet, ' the first available worksheet is selected. Dim sl As New SLDocument(TemplateDirectory & "Invoice.xlsx", "Invoice") ... ' Iterate through each Lineitem and set spreadsheet values For Each item As LineItem In SortedHost ... Next item sl.SaveAs(OutputFile) End Sub ... End Class123456789101112131415161718192021复制代码类型:[cpp]
数据绑定
数据绑定使将类属性绑定到System.Windows.Forms.Control属性变得更加容易和简单。在FrmProduct表单的Databind方法中,我们将所有必要的控件绑定到特定的Product对象。
Private Sub Databind(ByVal item As Product) ' Prior databindings must be clear before new databindings are added ClearDatabindings() ' Create Binding objects for all controls (i.e. ComboBox, TextBox, etc..). ' The data-bound property for controls is typically the Text property. ' The data source is a Product (i.e. 'item'). ' The data member is specified property on the Product object. cboCategory.DataBindings.Add("Text", item, "Category") nbrPrice.DataBindings.Add("Value", item, "UnitPrice") txtYear.DataBindings.Add("Text", item, "Year") txtTitle.DataBindings.Add("Text", item, "Name") nbrRating.DataBindings.Add("Text", item, "Rating") txtNumber.DataBindings.Add("Text", item, "Number") txtDescription.DataBindings.Add("Text", item, "Description") txtActor.DataBindings.Add("Text", item, "Actor") nbrQuantity.DataBindings.Add("Value", item, "Quantity")End Sub1234567891011121314151617181920复制代码类型:[cpp]
StringRandomGenerator
该StringRandomGenerator实际上是从一篇文章派生的自定义设计类在这里找到在CodeProject上。该GetRandom方法中附加的代码是每四分之一后加一个破折号Char。
Public Function GetRandom() As String ... If i > 0 AndAlso (i Mod 4) = 0 Then sb.Append("-") ... End Function