ZugferdInfoExt.vb
- ''
- '' This code is part of Document Solutions for PDF demos.
- '' Copyright (c) MESCIUS inc. All rights reserved.
- ''
- Imports System.IO
- Imports System.Drawing
- Imports System.Linq
- Imports System.Reflection
- Imports System.Collections.Generic
- Imports System.Globalization
- Imports GrapeCity.Documents.Pdf
- Imports GrapeCity.Documents.Text
- Imports s2industries.ZUGFeRD
- Imports GCTEXT = GrapeCity.Documents.Text
- Imports GCDRAW = GrapeCity.Documents.Drawing
-
- '' This sample demonstrates how to retrieve invoice data from a ZUGFeRD compliant XML attachment.
- '' All ZUGFeRD data is printed to the PDF generated by this sample.
- '' See ZugferdInfo for a similar sample that prints selected portions of the ZUGFeRD data.
-
- '' The sample PDF invoice containing ZUGFeRD data which this sample uses as input
- '' was generated by ZugferdInvoice.
- ''
- '' ZUGFeRD is a German e-invoicing standard based around PDF and XML file formats.
- '' Its poised to change the way invoices are handled and can be used by any sort of business.
- '' It will make invoice processing more efficient for senders and customers.
- '' For details please see What is ZUGFeRD?.
- ''
- '' This sample uses the ZUGFeRD-csharp package
- '' to parse the ZUGFeRD-compatible XML that is attached to the invoice.
- Public Class ZugferdInfoExt
- Function CreatePDF(ByVal stream As Stream) As Integer
- '' The sample invoice with ZUGFeRD data:
- Dim invoicePdf = Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")
-
- '' Output document:
- Dim doc = New GcPdfDocument()
- Using fs = File.OpenRead(invoicePdf)
- '' Load the ZUGFeRD compliant invoice PDF:
- Dim invoice = New GcPdfDocument()
- invoice.Load(fs)
-
- '' Get the ZUGFeRD attachment from the invoice by the ZUGFeRD 1.x standard file name:
- Dim attachment = invoice.EmbeddedFiles.Values.FirstOrDefault(Function(it) it.File.FileName = "ZUGFeRD-invoice.xml")
- If attachment IsNot Nothing Then
- Using xmlstream = attachment.GetStream()
- '' Load the invoice descriptor:
- Dim descriptor = InvoiceDescriptor.Load(xmlstream)
-
- Dim tl = New TextLayout(72)
- tl.MaxWidth = doc.PageSize.Width
- tl.MaxHeight = doc.PageSize.Height
- tl.MarginAll = tl.Resolution
- tl.DefaultTabStops = 24
-
- '' Recursively render all InvoiceDescriptor properties to text layout:
- tl.AppendLine($"{NameOf(InvoiceDescriptor)}:", _tfStrong)
- RenderProperties(descriptor, tl, 1)
-
- '' Write text layout to output PDF
- tl.PerformLayout(True)
- Dim topt = New TextSplitOptions(tl)
- While (True)
- Dim rest As TextLayout = Nothing
- Dim splitResult = tl.Split(topt, rest)
- doc.Pages.Add().Graphics.DrawTextLayout(tl, PointF.Empty)
- If splitResult <> SplitResult.Split Then
- Exit While
- End If
- tl = rest
- End While
- '' Done:
- doc.Save(stream)
- Return doc.Pages.Count
- End Using
- Else
- Return 0
- End If
- End Using
- End Function
-
- '' Recursively print all source's properties to text layout:
- Shared Sub RenderProperties(ByVal source As Object, ByVal tl As TextLayout, ByVal level As Integer)
- If source Is Nothing Then
- Return
- End If
- Dim props = source.GetType().GetProperties()
- For Each prop In props
- RenderProperty(prop, source, tl, level)
- Next
- End Sub
-
- '' Text formats for output:
- Private Shared ReadOnly _tfData = New TextFormat() With {
- .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf")),
- .FontSize = 12
- }
- Private Shared ReadOnly _tfStrong = New TextFormat(_tfData) With {
- .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuib.ttf"))
- }
- Private Shared ReadOnly _tfLabels = New TextFormat(_tfData) With {
- .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuii.ttf")),
- .FontSize = 11
- }
-
- '' Print a property:
- Shared Sub RenderProperty(ByVal prop As PropertyInfo, ByVal parent As Object, ByVal tl As TextLayout, ByVal level As Integer)
- Dim space = String.Empty
- For i = 0 To level - 1
- space += vbTab
- Next
- Dim name = prop.Name
- Dim value = prop.GetValue(parent, Nothing)
- If value Is Nothing Then
- tl.Append(space, _tfLabels)
- tl.AppendLine($"{name}:", _tfLabels)
- ElseIf (value.GetType().IsValueType OrElse value.GetType() Is GetType(String)) Then
- tl.Append(space, _tfLabels)
- tl.Append($"{name}: ", _tfLabels)
- tl.AppendLine(String.Format(CultureInfo.GetCultureInfo("en-US"), "{0}", value), _tfData)
- Else
- If TypeOf value Is IEnumerable(Of Object) Then
- Dim collection As IEnumerable(Of Object) = CType(value, IEnumerable(Of Object))
- Dim index = 0
- For Each item In collection
- tl.Append(space, _tfLabels)
- tl.AppendLine($"Collection item {name} [{index}]:", _tfStrong)
- index += 1
- RenderProperties(item, tl, level + 1)
- Next
- Else
- tl.Append(space, _tfLabels)
- tl.AppendLine($"Container {name}:", _tfStrong)
- RenderProperties(value, tl, level + 1)
- End If
- End If
- End Sub
- End Class
-